1

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

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

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

4

3 回答 3

2

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

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

为避免噩梦般的 Windows 引用问题,请将您的脚本放在一个文件中(例如 named foo.awk),然后使用awk -f foo.awk <input_files>where<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"
}

但我怀疑你误用了“>>”,而真的想要“>”。您可能还想> "output.txt"完全退出 awk 脚本,只在命令行上重定向输出,这样您就可以在同一个地方看到输入和输出文件。

我不知道什么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
于 2013-09-13T16:26:32.657 回答
2

如果您使用GNU awk的变量FILENAME包含正在读取的当前文件的名称。如果您一次将所有文件传递给awk然后您将使用ENDFILE而不是END

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

地点file1和地点file2

$ cat file1
1
2
3

$ cat file2
4
5
6

awk 在空白处拆分,因此您可能不需要显式设置 的值,FS并且EdMorton已经涵盖了重定向>>>. 还值得注意的是,这printf是一个语句而不是awk. 该脚本使用 Linux 引用而不是 Windows,但想法是相同的。

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

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

并称它为:

awk -f sum.awk <files>
于 2013-09-13T16:30:11.517 回答
1
awk "{sum+=$2} END {printf(\"%15d\n\", sum)}" *.txt > "output.txt"

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

for /f "delims=" %%a in ('awk "{sum+=$2} END {printf(\"%%15d\n\", sum)}" *.txt') do set "sum=%%a"
echo %sum%
于 2013-09-13T17:17:45.517 回答