Ant 속성에서 문자 바꾸기


90

속성 값을 가져 와서 특정 문자를 바꾸어 다른 속성으로 복사하는 간단한 방법이 있습니까?

말하십시오 propA=This is a value. 그 안에있는 모든 공백을 밑줄로 바꾸고 싶습니다 propB=This_is_a_value.

답변:


89

Ant Contrib 에서 propertyregex 태스크를 사용하십시오 .

나는 당신이 원한다고 생각합니다 :

<propertyregex property="propB"
               input="${propA}"
               regexp=" "
               replace="_"
               global="true" />

불행히도 주어진 예는별로 명확하지 않지만 시도해 볼 가치가 있습니다. 밑줄이없는 경우 어떻게되는지 확인해야합니다 defaultValue. 옵션 을 사용해야 할 수도 있습니다.


3
추가 defaultValue="${propA}"는 일반적인 검색 / 바꾸기 한 줄로 완벽합니다. 그렇지 않으면 일치하는 항목이 없으면 propB에 아무것도 넣지 않습니다 !! 감사!
David Robson

107

다음은 스크립팅이없고 ant-conrib와 같은 외부 jar가없는 솔루션입니다.

트릭은 ANT의 리소스를 사용하는 것입니다.

  • 소스 파일과 비슷하지만이 리소스의 문자열 값에서 스트림을 제공하는 "propertyresource"라는 리소스 유형이 하나 있습니다. 그래서 당신은 그것을로드하고 파일을 받아들이는 "복사"와 같은 모든 작업에서 사용할 수 있습니다
  • 모든 리소스를 속성 (예 : 파일)에로드 할 수있는 "loadresource"작업도 있지만이 작업은 속성 리소스도로드 할 수 있습니다. 이 작업을 통해 일부 토큰 변환을 적용하여 입력을 필터링 할 수 있습니다. 마지막으로 다음은 원하는 작업을 수행합니다.
<loadresource property="propB">
  <propertyresource name="propA"/>
  <filterchain>
    <tokenfilter>
      <filetokenizer/>
      <replacestring from=" " to="_"/>
    </tokenfilter>
  </filterchain>
</loadresource>

이것은 propA의 모든 ""를 "_"로 대체하고 결과를 propB에 배치합니다. "filetokenizer"는 전체 입력 스트림 (우리 속성)을 하나의 토큰으로 취급하고 그 위에 문자열 대체를 적용합니다.

다른 토큰 필터를 사용하여 다른 멋진 변환을 수행 할 수 있습니다. http://ant.apache.org/manual/Types/filterchain.html


7
감사! <filetokenizer/>비트를 떨어 뜨릴 수도 있습니다 . 코드가 없으면 (적어도 Ant v1.8.3에서는) 잘 작동합니다.
Matthias

Maven 내에서이 작업을 수행하려는 경우 stackoverflow.com/a/22969187/2163960
user2163960 2014

3
바닐라에서 작동하고 ant추가 라이브러리가 필요하지 않은 기술에 찬성 투표하십시오 .
Christopher Schultz

57

ant-contrib이 옵션이 아닌 경우 다음은 Java 1.6 이상을위한 휴대용 솔루션입니다.

<property name="before" value="This is a value"/>
<script language="javascript">
    var before = project.getProperty("before");
    project.setProperty("after", before.replaceAll(" ", "_"));
</script>
<echo>after=${after}</echo>

6
이 metod를 사용하는 경우 xml 구문 분석 문제를 방지하기 위해 스크립트를 CDATA로 묶는 것이 좋습니다. <script language = "javascript"> <! [CDATA [// Java 스크립트 코드는 '<'문자를 안전하게 사용할 수 있습니다. ]]> </ script>
Jan Arciuchiewicz

3
@dnault Javascript에는 replaceAll문자열에 대한 기능 이 없습니다 . before.replace( /\s/g, "_" )대신 사용하십시오 .
Larry Battle

3
@LarryBattle는 project.getProperty()반환 java.lang.String하므로, replaceAll()이 경우에 적합하다. 를 사용하려면 다음을 사용하여 replace()'before'를 기본 JavaScript 문자열로 변환 할 수 있습니다.before = new String(before);
dnault

1
project.setNewPropertysetProperty이전 속성 값을 덮어 쓸 수 있으므로 더 이식성이 있습니다 . before부동산에 쓸 수도 있습니다.
Jarekczek

Rhino가 필요합니다
vintproykt

26

Ant 내장 기능 사용하는 솔루션을 원하는 경우 다음을 고려하십시오.

<target name="replace-spaces">
    <property name="propA" value="This is a value" />
    <echo message="${propA}" file="some.tmp.file" />
    <loadfile property="propB" srcFile="some.tmp.file">
        <filterchain>
            <tokenfilter>
                <replaceregex pattern=" " replace="_" flags="g"/>
            </tokenfilter>
        </filterchain>
    </loadfile>
    <echo message="$${propB} = &quot;${propB}&quot;" />
</target>

출력은 ${propB} = "This_is_a_value"


2
누가 some.tmp.file을 정리합니까?
ceving

다른 사람들이 이것을 사용하기를 원할 수 있기 때문에; </ loadfile> 뒤에 <delete file = "some.tmp.file"/>을 추가합니다. 답변 : 질문 @ceving
terix2k11

8

sed와 같은 외부 앱을 사용하십시오.

<exec executable="sed" inputstring="${wersja}" outputproperty="wersjaDot">
  <arg value="s/_/./g"/>
</exec>
<echo>${wersjaDot}</echo>

Windows를 실행하는 경우 "gnuwin32 sed"를 검색합니다.

이 명령 s/_/./g은 every _. 다음으로 대체합니다 . 이 스크립트는 창에서 잘 작동합니다. 리눅스에서 arg는 인용이 필요할 수 있습니다.


8

두 가지 가능성 :

스크립트 작업 및 내장 자바 스크립트 엔진을 통해 (jdk> = 1.6을 사용하는 경우)

<project>

 <property name="propA" value="This is a value"/>

 <script language="javascript">
  project.setProperty('propB', project.getProperty('propA').
   replace(" ", "_"));
 </script>
 <echo>$${propB} => ${propB}</echo>

</project>

또는 Ant addon Flaka 사용

<project xmlns:fl="antlib:it.haefelinger.flaka">

 <property name="propA" value="This is a value"/>

 <fl:let> propB := replace('${propA}', '_', ' ')</fl:let>

 <echo>$${propB} => ${propB}</echo>

</project>

기존 속성 propA를 덮어 쓰려면 propB를 propA로 바꾸면됩니다.


7

다음은 Uwe Schindler의 답변의 보다 일반화 된 버전입니다 .

macrodef를 사용하여 사용자 지정 작업을 만들 수 있습니다 .

<macrodef name="replaceproperty" taskname="@{taskname}">
    <attribute name="src" />
    <attribute name="dest" default="" />
    <attribute name="replace" default="" />
    <attribute name="with" default="" />
    <sequential>
        <loadresource property="@{dest}">
            <propertyresource name="@{src}" />
            <filterchain>
                <tokenfilter>
                    <filetokenizer/>
                    <replacestring from="@{replace}" to="@{with}"/>
                </tokenfilter>
            </filterchain>
        </loadresource>
    </sequential>
</macrodef>

다음과 같이 사용할 수 있습니다.

<replaceproperty src="property1" dest="property2" replace=" " with="_"/>

이 작업을 여러 번 수행하는 경우 매우 유용합니다.


3

이전 답변 보다 더 완전한 예제 추가

<property name="propB_" value="${propA}"/>
<loadresource property="propB">
  <propertyresource name="propB_" />
  <filterchain>
    <tokenfilter>
      <replaceregex pattern="\." replace="/" flags="g"/>
    </tokenfilter>
  </filterchain>
</loadresource>

1

대답에 대한 FYI 는 Ant 속성의 문자 바꾸기 -Maven 실행 내에서 이것을 사용하려는 경우 maven 변수를 직접 참조 할 수 없습니다. 다음과 같은 것이 필요합니다.

...
<target>
<property name="propATemp" value="${propA}"/>
    <loadresource property="propB">
    <propertyresource name="propATemp" />
...

대체 무슨 부품 관련 " ""_"?
Jin Kwon

또한 받는다는에, 당신은 사용 재산의 필요성을 피할 수 있습니다 propATemp 대체하여 <propertyresource name="propATemp"/>함께<string value="${propA}"/>
에드 랜달

1

속성은 변경할 수 없지만 antContrib 변수 ( http://ant-contrib.sourceforge.net/tasks/tasks/variable_task.html )는 변경할 수 있습니다.

다음은 var에서 찾기 / 바꾸기를 수행하는 매크로입니다.

    <macrodef name="replaceVarText">
        <attribute name="varName" />
        <attribute name="from" />
        <attribute name="to" />
        <sequential>
            <local name="replacedText"/>
            <local name="textToReplace"/>
            <local name="fromProp"/>
            <local name="toProp"/>
            <property name="textToReplace" value = "${@{varName}}"/>
            <property name="fromProp" value = "@{from}"/>
            <property name="toProp" value = "@{to}"/>

            <script language="javascript">
                project.setProperty("replacedText",project.getProperty("textToReplace").split(project.getProperty("fromProp")).join(project.getProperty("toProp")));
            </script>
            <ac:var name="@{varName}" value = "${replacedText}"/>
        </sequential>
    </macrodef>

그런 다음 다음과 같이 매크로를 호출합니다.

<ac:var name="updatedText" value="${oldText}"/>
<current:replaceVarText varName="updatedText" from="." to="_" />
<echo message="Updated Text will be ${updatedText}"/>

위의 코드는 javascript split then join을 사용하며 정규식보다 빠릅니다. "로컬"속성은 자바 스크립트에 전달되므로 속성 유출이 없습니다.


0

또는 ... 자신의 작업 을 시도 할 수도 있습니다.

자바 코드 :

class CustomString extends Task{

private String type, string, before, after, returnValue;

public void execute() {
    if (getType().equals("replace")) {
        replace(getString(), getBefore(), getAfter());
    }
}

private void replace(String str, String a, String b){
    String results = str.replace(a, b);
    Project project = getProject();
    project.setProperty(getReturnValue(), results);
}

..all getter and setter..

개미 스크립트

...
<project name="ant-test" default="build">

<target name="build" depends="compile, run"/>

<target name="clean">
    <delete dir="build" />
</target>

<target name="compile" depends="clean">
    <mkdir dir="build/classes"/>
    <javac srcdir="src" destdir="build/classes" includeantruntime="true"/>
</target>

<target name="declare" depends="compile">
    <taskdef name="string" classname="CustomString" classpath="build/classes" />
</target>

<!-- Replacing characters in Ant property -->
<target name="run" depends="declare">
    <property name="propA" value="This is a value"/>
    <echo message="propA=${propA}" />
    <string type="replace" string="${propA}" before=" " after="_" returnvalue="propB"/>
    <echo message="propB=${propB}" />
</target>

콘솔:

run:
     [echo] propA=This is a value
     [echo] propB=This_is_a_value
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.