AWK。循环遍历目录和汇总列

时间:2013-09-13 16:11:40

标签: windows batch-file awk printf

我正在尝试对列进行求和,并将输出与文件名一起写入。我写了以下一行,效果很好并输出总和。我正在努力做两件事。将文件名与输出一起传递,如何遍历当前目录并仅处理* .txt文件。请注意我通过Windows 7中的批处理文件(.bat)运行它.Thks

awk -F"\t" "{ sum+=$2} END {printf ("""%%15d""",sum) >>"output.txt"}" input.TXT 

另外如何将printf(“”“%% 15d”“”,sum)的输出传递给变量?

3 个答案:

答案 0 :(得分:2)

how do i loop through the current directory and process only *.txt files是您操作系统的问题,而不是awk。

每个文件名都存储在awk中的FILENAME变量中。

为避免噩梦般的Windows引用问题,请将您的脚本放在一个文件中(例如名为foo.awk),然后使用awk -f foo.awk <input_files>运行该文件,其中<input_files>表示提供的输入文件列表通过您的操作系统(在UNIX中它是*.txt或类似的)。

根据您发布的脚本,foo.awk将包含:

BEGIN { FS="\t" }
{ sum[FILENAME] += $2 }
END {
    for (i=1;i<ARGC;i++)
        printf "%s %15d\n", ARGV[i], sum[ARGV[i]] >> "output.txt"
}

但我怀疑你误用“&gt;&gt;”并且真的想要“&gt;”代替。您可能还想完全从awk脚本中取出> "output.txt",只需在命令行上重定向输出,这样您就可以在同一位置看到输入和输出文件。

我不知道how can one pass the output of printf ("""%%15d""",sum) to a variable?的含义。

要使用类似打印的格式并将结果分配给您使用sprintf()而不是printf的变量,例如:

$ awk 'BEGIN{ foo = sprintf("%s",3.79); print foo}'
3.79

$ awk 'BEGIN{ foo = sprintf("%d",3.79); print foo}'
3

$ awk 'BEGIN{ foo = sprintf("%.4f",3.79); print foo}'
3.7900

答案 1 :(得分:2)

如果您使用的是GNU awk,则变量FILENAME包含要读取的当前文件的名称。如果您一次将所有文件传递到awk,那么您将使用ENDFILE代替END

$ awk '{sum+=$1}ENDFILE{print FILENAME,sum; sum=0}' file1 file2
file1 6
file2 15

file1file2的位置:

$ cat file1
1
2
3

$ cat file2
4
5
6

Awk在空格上拆分,因此您可能不需要显式设置FSEdMorton的值已经涵盖重定向> vs >>。值得注意的是printfawk中不是函数的语句。该脚本使用Linux引用而非Windows,但想法是相同的。

要绕过Windows引用,您可以将脚本放在一个文件中,例如sum.awk

BEGIN { 
    FS="\t" 
}     
{ 
    sum+=$2
}  
END {
    printf "%15d",sum >> "output.txt"
}

并称之为:

awk -f sum.awk <files>

答案 2 :(得分:1)

awk "{sum+=$2} END {printf(\"%15d\n\", sum)}" *.txt > "output.txt"

这在Windows cmd命令提示符下运行良好。要在Windows命令语言脚本(也称为“批处理”)中使用它,您必须将百分号加倍。

for /f "delims=" %%a in ('awk "{sum+=$2} END {printf(\"%%15d\n\", sum)}" *.txt') do set "sum=%%a"
echo %sum%