不打印换行符的awk

222
我希望在每次迭代中将变量 sum/NR 并排打印。我们如何避免 awk 在每次迭代中打印换行符?在我的代码中,默认情况下会在每次迭代中打印一个换行符。
for file in cg_c ep_c is_c tau xhpl
printf "\n $file" >> to-plot.xls
    for f in 2.54 1.60 800 
        awk '{sum+=$3}; END  {print  sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls
    done
done

我希望输出结果像这样

cg_c ans1  ans2  ans3  
ep_c ans1  ans2  ans3 
is_c ans1  ans2  ans3
tau  ans1  ans2  ans3 
xhpl ans1  ans2  ans3

我目前的输出如下:

**cg_c**
ans1
ans2
ans3
**ep_c**
ans1
ans2
ans3
**is_c**
ans1
ans2
ans3
**tau**
ans1
ans2
ans3
**xhpl**
ans1
ans2
ans3
7个回答

271

awk '{sum+=$3}; END {printf "%f",sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls

print默认会插入一个新行,因此使用printf来避免这种情况。


6
请注意,printf 解释 %s,因此请使用 printf "%s" whatever 而不是 printf whatever - Matthieu
5
printf "%s",whatever 你忘了逗号。你也可以添加更多的变量,并用逗号分隔它们。 - Hielke Walinga

86

AWK中的输出记录分隔符(ORS)变量默认为“\n”,并在每行之后打印。如果您希望连续打印所有内容,可以将其更改为“ ”BEGIN节。


6
你甚至可能想将它设置为 ""(没有空格),以完全没有任何分隔。 - mschilli
11
像这样:awk 'BEGIN {ORS="\t"} {sum+=$3}; END {print sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls 的意思是在 ${file}_${f}_v1.xls 文件中对第三列的值进行求和,并计算平均数,最后将结果添加到 to-plot-p.xls 文件的末尾。awk 是一个用于文本处理和数据提取的命令行工具。 - Fredrik Erlandsson
2
如果您想打印显示进度的计数器,可以使用ORS="\r" - Skippy le Grand Gourou

77

我猜很多人进入这个问题是想要避免在 awk 中的换行符。因此,我将提供一个解决方案,仅解决这个问题,因为特定上下文的答案已经被解决了!

awk 中,print 命令在打印后自动插入一个输出记录分隔符 (ORS)。 ORS 表示“输出记录分隔符”,默认为换行符。所以当你输入 print "hi" ,awk 会输出 "hi" 后跟一个换行符。

可以通过两种不同的方式来更改这个行为:使用空的 ORS 或使用 printf 命令。

使用空的 ORS

awk -v ORS= '1' <<< "hello
man"

这会返回"helloman",全部在一起。

问题在于,并非所有的awk都接受设置空的ORS,所以您可能需要设置另一个记录分隔符。

awk -v ORS="-" '{print ...}' file
例如:
awk -v ORS="-" '1' <<< "hello
man"

返回 "hello-man-"。

使用 printf (更可取)

尽管 print 在记录后附加 ORS , 但是 printf 不会。因此,printf "hello" 只会打印 "hello",什么也不会多出来。

$ awk 'BEGIN{print "hello"; print "bye"}'
hello
bye
$ awk 'BEGIN{printf "hello"; printf "bye"}'
hellobye

最后要注意的是,通常这会缺少一个最终的换行符,因此shell提示符将与输出的最后一行在同一行上。为了解决这个问题,请使用END {print ""},以便在所有处理完成后打印一个新行。

$ seq 5 | awk '{printf "%s", $0}'
12345$
#    ^ prompt here

$ seq 5 | awk '{printf "%s", $0} END {print ""}'
12345

5
一种方法
awk '/^\*\*/{gsub("*","");printf "\n"$0" ";next}{printf $0" "}' to-plot.xls

2
小提醒:永远不要使用 printf $0,因为 $0 可能包含诸如 %F 等字符串...以下示例可能会失败(至少在 GAWK 3.1.5 中):echo "%F"|awk '{printf $0}'。请改用 printf "%s",$0 - Vlad

4
您可以像这样动态地使用ORS:
awk '{ORS="" ; print($1" "$2" "$3" "$4" "$5" "); ORS="\n"; print($6-=2*$6)}' file_in > file_out

很酷,可以在Kubernetes集群中一行代码中获取节点的IP地址。k get nodes -o wide --no-headers | awk '{ORS=" "; print $6 }' - Dr. Mian

1
如果Perl是一个选项,这里有一个使用fedorqui的示例的解决方案:
seq 5 | perl -ne 'chomp; print "$_ "; END{print "\n"}'
解释: chomp删除换行符 print "$_ "打印每一行,并添加一个空格 END{}块用于打印换行符
输出:1 2 3 4 5

0
这里介绍了一种 awk 的方法,可以避免使用 printfEND(假设您的输入少于 500 MB):
seq 199 | 

mawk NF=NF RS='^$' FS='\n' OFS= 
123456789101112131415161718192021222324252627282930313233343
536373839404142434445464748495051525354555657585960616263646
566676869707172737475767778798081828384858687888990919293949
596979899100101102103104105106107108109110111112113114115116
117118119120121122123124125126127128129130131132133134135136
137138139140141142143144145146147148149150151152153154155156
157158159160161162163164165166167168169170171172173174175176
177178179180181182183184185186187188189190191192193194195196
197198199

(为了易读性重新格式化 - 这是一行文本,末尾有\n

如果你只是想在它们之间放一个空格:

seq 19 | 

mawk 'NF && --NF' RS='^$' FS='\n'         
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

如果您不介意多一个尾随空格,那么它会更简单。

mawk NF=NF RS='^$' FS='\n' 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接