使用 Ant 连接 CSV 文件两列中的数据

Concatenate data from two columns of a CSV file using Ant

有没有办法在 csv 文件中创建一个新列,其中包括连接其他两个列的 "-" - 使用 Ant?

示例:

customer,deal,NEWFIELD
200000042,23,200000042-23
200000042,34,200000042-34
200000042,35,200000042-35    
200000042,65,200000042-65

您可以使用 Ant filterchains 来完成此操作,类似于这个基本示例:

<property name="in.file" value="input.txt" />
<property name="out.file" value="output.txt" />
<property name="new.field" value="NEWFIELD" />
<property name="sep.char" value="," />

<loadfile srcfile="${in.file}" property="file.head">
  <filterchain>
    <headfilter lines="1" />
    <striplinebreaks />
  </filterchain>
</loadfile>
<loadfile srcfile="${in.file}" property="file.body">
  <filterchain>
    <headfilter skip="1" />
    <tokenfilter>
        <replaceregex pattern="^([^${sep.char}]*)${sep.char}([^${sep.char}]*)$"
                      replace="${sep.char}${sep.char}-" />
    </tokenfilter>
  </filterchain>
</loadfile>

<echo file="${out.file}">${file.head}${sep.char}${new.field}
${file.body}</echo>

两个<loadfile>任务用于处理文件头和正文,然后一个简单的<echo>任务写入输出。由于 CSV 文件中的字段数量很少,因此此处使用简单的正则表达式。 replaceregex 使用捕获组获取行中的前两个字段,然后在 replace 字符串中组装所需的输出。

如果有多个字段,那么第二个 loadfile 中的 scriptfilter 可能更易于使用:

<loadfile srcfile="${in.file}" property="file.body">
  <filterchain>
    <headfilter skip="1" />
    <scriptfilter language="javascript"><![CDATA[
      var line = self.getToken( );
      var fields = line.split( "," );
      self.setToken( line + "," + fields[0] + "-" + fields[1] );
    ]]></scriptfilter>
  </filterchain>
</loadfile>

这个取行,拆分它,然后附加所需的字段。

如果您的数据包含嵌入的逗号,那么这里的两个示例都不起作用。

嵌入像Groovy这样的脚本语言会更简单吗?

示例

├── build.xml
├── src
│   └── file1.csv
└── target
    └── file1.csv

src/file1.csv

customer,deal
200000042,23
200000042,34
200000042,35
200000042,65

target/file1.csv

customer,deal,customer-deal
200000042,23,200000042-23
200000042,34,200000042-34
200000042,35,200000042-35
200000042,65,200000042-65

build.xml

<project name="demo" default="build">

  <available classname="org.codehaus.groovy.ant.Groovy" property="groovy.installed"/>

  <target name="build" depends="install-groovy">
    <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>

    <groovy>
      ant.mkdir(dir:"target")

      new File("target/file1.csv").withWriter {
        new File("src/file1.csv").splitEachLine(",") { customer, deal ->
           it.println "${customer},${deal},${customer}-${deal}"
        }
      }
    </groovy>
  </target>

  <target name="install-groovy" description="Install groovy" unless="groovy.installed">
    <mkdir dir="${user.home}/.ant/lib"/>
    <get dest="${user.home}/.ant/lib/groovy.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.4.7/groovy-all-2.4.7.jar"/>
    <fail message="Groovy has been installed. Run the build again"/>
  </target>

</project>