awk OFS没有产生预期价值

时间:2014-10-07 17:58:08

标签: bash awk

我有一个文件

[root@nmk~]# cat file
abc>
sssd>
were>

我运行awk命令的这两种变体

[root@nmk~]# cat file | awk -F\>  ' { print $1}' OFS=','
abc
sssd
were

[root@nmk~]# cat file | awk -F\>  ' BEGIN { OFS=","}  { print $1}' 
abc
sssd
were
[root@nmk~]# 

但是我的预期输出是

abc,sssd,were

我的命令中缺少什么?

4 个答案:

答案 0 :(得分:6)

您对FS,OFS,RS和ORS的含义/用途感到有点困惑。再看一下手册页。我认为这就是你想要做的事情:

$ awk -F'>' -v ORS=',' '{print $1}' file
abc,sssd,were,$

但这可能更接近您真正想要的输出:

$ awk -F'>' '{rec = rec (NR>1?",":"") $1} END{print rec}' file
abc,sssd,were

或者如果您不想将整个输出缓冲为字符串:

$ awk -F'>' '{printf "%s%s", (NR>1?",":""), $1} END{print ""}' file
abc,sssd,were

答案 1 :(得分:2)

awk -F\> -v ORS=""  'NR>1{print ","$1;next}{print $1}' file

在最后打印换行符:

awk -F\> -v ORS=""  'NR>1{print ","$1;next}{print $1} END{print "\n"}' file

输出:

abc,sssd,were

答案 2 :(得分:1)

awk中的每一行输入都是记录,因此您要设置的是输出记录分隔符ORSOFS变量包含Output Field 分隔符,用于分隔每行的不同部分。

由于您要将输入字段分隔符FS>OFS设置为,,因此您可以轻松查看这些工作如何在>

之后在文件的每一行添加内容
awk 'BEGIN { FS=">"; OFS=","} {$1=$1} 1' <<<$'abc>def\nsssd>dsss\nwere>wolf'
abc,def
sssd,dsss
were,wolf

所以你想设置ORS。默认记录分隔符是换行符,因此无论您设置ORS还是有效地替换输入中的换行符。但这意味着如果输入的最后一行有一个换行符 - 通常是一个案例 - 最后一行也会获得新ORS的副本:

awk 'BEGIN { FS=">"; ORS=","}  1' <<<$'abc>def\nsssd>dsss\nwere>wolf'
abc>def,sssd>dsss,were>wolf,

它根本不会得到换行符,因为换行符被解释为输入记录分隔符并转换为输出记录分隔符 - 它变成了最后一个逗号。

因此,您必须更明确地了解自己要做的事情:

  awk 'BEGIN { FS=">"          } # split input on >
      (NR>1) { printf ","      } # if not the first line, print a ,
             { printf "%s", $1 } # print the first field (everything up to the first >) 
         END { printf "\n"     } # add a newline at the end
      ' <<<$'abc>\nsssd>\nwere>'

哪个输出:

abc,sssd,were

答案 3 :(得分:0)

通过sed,

$ sed ':a;N;$!ba;s/>\n/,/g;s/>$//' file
abc,sssd,were

通过Perl,

$ perl -00pe 's/>\n(?=.)/,/g;s/>$//' file
abc,sssd,were