AWK:如果这个是正则表达式,有没有办法将OFS设置为FS?

在awk中,字段(或记录)分隔符FS(或RS)可以设置为正则表达式.
它非常适合获取任何单个字段,但是一旦设置了这些字段,字段分隔符就会“消失”.
echo "a|b-c|d" | awk 'BEGIN{FS="[|-]"} {$3="z"}1'
a b z d

在这种情况下,输出字段分隔符OFS默认设置为空格.

不幸的是,这种语句OFS = FS =“[| – ]”不起作用,因为它将OFS设置为一个字符串.

我知道如果有多个选择,awk选择输出字段分隔符可能会变得棘手,但是如果没有新字段,则可以保留当前的字段.

那么,是否有一种简单的方法可以将OFS设置为与FS完全相同的正则表达式,这样我就可以得到它?

echo "a|b-c|d" | awk '... {$3="z"}1'
a|b-z|d

或者,有没有办法捕获数组中的所有分隔符?

同样的问题也适用于记录分隔符RS(及其相关的ORS)

解决方法

正如您已经提到的,没有办法根据每种情况下使用的FS动态设置OFS.如果正则表达式是RS而不是FS,你可以使用RT(事实上,我只是看到anubhava的答案就是这样,很好!).

但是,如果你有GNU awk还有另一种方法:如column replacement with awk,with retaining the format (Ed Morton’s answer)所示,你可以使用split(),特别是它的第四个参数.为什么?因为它在每个切片之间存储分隔符:

gawk 'BEGIN{FS="[|-]"}                     # set FS
     {split($0,a,FS,seps)               # split based on FS and ...
                                           # ...  store pieces in the array seps()
      a[3]="z"                             # change the 3rd field
      for (i=1;i<=NF;i++)                  # print the data back
           printf "%s%s",a[i],seps[i]    # keeping the separators
      print ""                             # print a new line
     }'

作为单线:

$gawk 'BEGIN{FS="[|-]"} {split($0,seps); a[3]="z"; for (i=1;i<=NF;i++) printf "%s%s",seps[i]; print ""}' <<< "a|b-c|d"
a|b-z|d

split(string,array [,fieldsep [,seps ] ])

Divide string into pieces separated by fieldsep and store the pieces in array and the separator strings in the seps array. The first piece is stored in array07002,the second piece in array07003,and so forth. The string value of the third argument,fieldsep,is a regexp describing where to split string (much as FS can be a regexp describing where to split input records). If fieldsep is omitted,the value of FS is used. split() returns the number of elements created. seps is a gawk extension,with seps[i] being the separator string between array[i] and array[i+1]. If fieldsep is a single space,then any leading whitespace goes into seps[0] and any trailing whitespace goes into seps[n],where n is the return value of split() (i.e.,the number of elements in array).

相关文章

linux常用进程通信方式包括管道(pipe)、有名管道(FIFO)、...
Linux性能观测工具按类别可分为系统级别和进程级别,系统级别...
本文详细介绍了curl命令基础和高级用法,包括跳过https的证书...
本文包含作者工作中常用到的一些命令,用于诊断网络、磁盘占满...
linux的平均负载表示运行态和就绪态及不可中断状态(正在io)的...
CPU上下文频繁切换会导致系统性能下降,切换分为进程切换、线...