AWK:使用不同的输出内联分离器和不同的输出EOF分离器打印每隔一个字段?

时间:2017-07-20 21:24:22

标签: awk

这个问题与using awk to print every second field有关,但我整齐地打印它有问题

$ cat printEachSecondColumnValue 
1,11,111,1111,11111
2,22,222,2222,22222
3,33,333,3333,33333
4,44,444,4444,44444
5,55,555,5555,55555
6,66,666,6666,66666
$ gawk -v RS=, -v ORS="\n" '0==NR%2' printEachSecondColumnValue 
11
1111
22
2222
33
3333
44
4444
55
5555
66
6666
$ gawk -v RS=, -v ORS="," '0==NR%2' printEachSecondColumnValue 
11,1111,22,2222,33,3333,44,4444,55,5555,66,6666,

虽然我想得到

11,1111
22,2222
33,3333
44,4444
55,5555
66,6666

您能否逐一解释命令的行为以及如何以不同方式定义内联分隔符和EOF以获取两列?

1 个答案:

答案 0 :(得分:2)

  

虽然我想得到

11,1111
22,2222
33,3333
44,4444
55,5555
66,6666
赦免这种明显的入侵,但那只是

awk 'BEGIN { FS = OFS = ","} { print $2, $4 }'

给定数据。

要打印偶数字段而不管有多少字段,我们可以用循环替换print

awk 'BEGIN {
       FS = OFS = ","
     }                                                    
     {                                                                          
       for (i = 2; i <= NF; i += 2) {                                           
         printf "%s", i                                                         
         if (i + 2 <= NF)                                                       
           printf OFS                                                           
       }                                                                        
       printf "\n"                                                              
     }' 

逗号的替代逻辑:

       for (i = 2; i <= NF; i += 2) {
         if (i > 2)
           printf OFS
         printf "%s", i
       }

现在,对于一些不同的东西。如果我们编辑字段到我们想要的集合怎么办?然后我们可以用print打印它们!

awk 'BEGIN { FS = OFS = ","}
     {
       for (i = 2; i <= NF; i += 2) {
         j = i/2
         $j = $i
       }    
       NF = j
       print
     }'

当我们分配给NF时,这意味着现在有很多字段。 如果我们更改了任何字段,或更改了NF,则默认情况下$0打印的print的值会通过将字段值与OFS组合在一起来重新计算它们。

Smarter Awk,在TXR语言中实现为Lisp宏:

$ txr -e '(awk (:set fs "," ofs fs)
               (t (set f (select f (range 1 : 2)))
                  (prn)))'
1,2,3,4,5,6,7,8,9,10
2,4,6,8,10
1,2,3,4
2,4

这里(:set ...)子句用于设置初始变量; fs类似于FS并设置为逗号; ofs设置为fs

t表示布尔值为true:此子句为每条记录触发。然后,我们通过选择第二个,第三个,第四个来编辑字段列表f,这些字段由从零开始的列表(1 3 5 7 9 ...)指示。我们使用(range 1 : 2)生成此索引列表的无限懒惰版本,并将其提供给select函数。

分配给f会导致记录变量rec(类似于$0)重新构成ofs。没有参数的prn函数打印rec

我们可以通过将f的输出作为rec的参数直接提供给select来摆脱prn的修改和设置apply的副作用}:

txr -e '(awk (:set fs "," ofs fs)
             (t [apply prn (select f (range 1 : 2))])))'

“将prn应用于偶数字段,ofs为逗号。”