如何使用gawk脚本编写其他文件?

时间:2014-07-08 20:20:13

标签: batch-file csv awk overwrite gawk

我已经编写了一个用于从CSV文件中删除重复项的代码。现在我想用原始名称保存文件。我不想用不同的名字保存。以下是批处理脚本:

代码:

@echo off

C:\sw\awk\bin\gawk.exe "!x[$0]++" *.csv > "{print FILENAME, $0 > FILENAME ".csv"}" file*

我的目标是:我想构建可在任何CSV文件上运行的动态批处理脚本。不应该有任何类型的依赖(文件名)。

Error is :
The filename, directory name or volume label syntax is incorrect. 

请帮助我。

感谢。

2 个答案:

答案 0 :(得分:2)

此批处理文件正尝试将gawk的输出重定向到名为{print FILENAME, $0 > FILENAME的文件,该文件不是有效的文件名。

目前,gawk代码生成一个输出,该输出省略了目录中所有CSV文件中的所有重复行。

如果要单独省略每个CSV文件中的重复行并单独写出每个文件,则需要在批处理文件中循环以将每个CSV文件单独呈现给gawk脚本并输出每个修改后的文件个别。你可以这样做(假设tmp.tmp不是文件夹中的现有文件):

for %%f in (*.csv) do (
  gawk.exe "!x[$0]++" "%%f" >tmp.tmp
  copy tmp.tmp "%%f"
)
del tmp.tmp

作为警告说明,如果您通过标准输出将正在阅读的文件写入DOS或Windows,则可以在阅读之前覆盖正在阅读的文件。这就是上面的代码写入临时文件然后将临时文件复制到原始文件的原因。

答案 1 :(得分:1)

您的尝试存在许多问题。首先,你不能写入你正在阅读的同一个文件(至少,当你从中读取时)。其次,您在awk脚本之外使用FILENAME特殊变量awk,它不存在。

以下内容可能适用于单个文件。它使用行作为关联数组的键并使用行号作为值来读取整个文件。然后在END块中,它按值的顺序打印出数组,写入刚刚读取的文件。

gawk "!($0 in a) {a[$0] = NR} END {PROCINFO[\"sorted_in\"]=\"@val_num_asc\"; for(x in a) print x >FILENAME}"