使用awk或gawk脚本设计输出

时间:2014-11-26 07:40:29

标签: awk gawk

我有一个awk脚本,它在.txt文件中给出了我想要的结果,但我关心的是如何给出结果:我将它们全部放在一行中,我想设计它。

20140201 -73828274 20140202 7376288374 20140203 3837482437 ....... 20140228 -73629277

我希望输出以这种格式显示

20140201          -73828274
20140202         7376288374
20140203         3837482437
n                  n
n                  n
n                  n
20140228           73629277

我希望日期在一边,相应的总数在日期前面

这里使用了awk脚本

$ for file in *.txt;do awk -F,'NR==1{header=$0; next} {a[$1]+=$6+$14} END {for (i in a) {print i, a[i]};}' $file; done > red.txt

任何想法?

4 个答案:

答案 0 :(得分:1)

您可以使用print代替printf。更改END{}脚本的awk部分,如下所示:

END {for (i in a) {printf "%d\t%d\n", i, a[i]};}

在两个值(%d)之间,它会打印一个标签(\t),最后会打印一个换行符(\n)。

或完整的命令:

for file in *.txt;do awk -F,'NR==1{header=$0; next} {a[$1]+=$6+$14} END {for (i in a) {printf "%d\t%d\n", i, a[i]};}' $file; done > red.txt

答案 1 :(得分:1)

使用greptr,如下所示

$ grep -oP '\S+\s+\S+' file | tr ' ' '\t'
20140201    -73828274
20140202    7376288374
20140203    3837482437
20140228    -73629277

答案 2 :(得分:1)

你不需要shell循环,awk完全能够处理多个文件,例如使用GNU awk进行ENDFILE并删除数组:

awk -F, 'FNR>1{a[$1]+=$6+$14} ENDFILE{for (i in a) print i, a[i]; delete a}' *.txt > red.txt

由于您未提供任何样本输入,因此上述情况显然未经测试。

您发布的脚本无法生成您显示的输出。在awk脚本运行后,您正在执行其他操作,以使其对您显示,就好像输出文件的所有行都在一行上一样。我怀疑你可能没有再引用一个变量(比如你没有在脚本中引用$file)并做了类似的事情:

var=$(cat red.txt)
echo $var

一旦您的脚本完成运行,只需执行cat red.txt,您就会看到内容并非全部在您声明的一行中。

答案 3 :(得分:0)

使用awk

进行简单的方法
awk -v RS=" " 'ORS=NR%2?RS:"\n"' file
20140201 -73828274
20140202 7376288374
20140203 3837482437

首先我们将记录选择器设置为空格,因此每个日期都是一个新行 然后我们根据奇数和偶数行将输出记录选择器更改为空格或换行符。


您也可以使用getline,但请注意,getline有很多陷阱。

awk -v RS=" " '{a=$0;getline;print a,$0}' file
20140201 -73828274
20140202 7376288374
20140203 3837482437

通过这种方式,您可以使用printf

更多地控制输出