如果没有awk重新编译使用OFS值作为分隔符的记录,您不能将值分配给字段。相反,使用正则表达式来描述整个记录,并替换存在于您关心的字段所在的记录部分。例如用GNU AWK(其它awks - 用火柴()/ SUBSTR()和[[:空间:]]):
$ cat foo
foo bar quux # single space, single tab
foo bar quux # single space, double space, triple space
$ awk '{ print gensub(/^(\s*(\S+\s+){1})\S+(.*)/,"\\1blah\\3","") }' foo
foo blah quux # single space, single tab
foo blah quux # single space, double space, triple space
变化{1}
的1
适合不过许多领域之前要替换领域:
$ awk '{ print gensub(/^(\s*(\S+\s+){2})\S+(.*)/,"\\1blah\\3","") }' foo
foo bar blah # single space, single tab
foo bar blah # single space, double space, triple space
$ awk '{ print gensub(/^(\s*(\S+\s+){3})\S+(.*)/,"\\1blah\\3","") }' foo
foo bar quux blah single space, single tab
foo bar quux blah single space, double space, triple space
GAWK还包含一个名为patsplit函数(),其工作方式类似于分裂(),但代替仅存储所得到的字符串中的字段,它也存储的字段之间的空间中的第二阵列,从而可以在这些阵列上使用循环以获得原始空间(如果更清晰):
$ awk '{ nf = patsplit($0,fld,/\S+/,sep); fld[2]="blah"; for (i=1;i<=nf;i++) printf "%s%s", sep[i-1], fld[i]; print "" }' foo
foo blah quux # single space, single tab
foo blah quux # single space, double space, triple space
$ awk '{ nf = patsplit($0,fld,/\S+/,sep); fld[3]="blah"; for (i=1;i<=nf;i++) printf "%s%s", sep[i-1], fld[i]; print "" }' foo
foo bar blah # single space, single tab
foo bar blah # single space, double space, triple space
以下是如何patsplit()被打破每一条记录:
$ awk '{ nf = patsplit($0,fld,/\S+/,sep); print "\n" $0; for (i=0;i<=nf;i++) print "<" i ":" fld[i]
":" sep[i] ">" }' foo
foo bar quux # single space, single tab
<0::>
<1:foo: >
<2:bar: >
<3:quux: >
<4:#: >
<5:single: >
<6:space,: >
<7:single: >
<8:tab:>
foo bar quux # single space, double space, triple space
<0:: >
<1:foo: >
<2:bar: >
<3:quux: >
<4:#: >
<5:single: >
<6:space,: >
<7:double: >
<8:space,: >
<9:triple: >
<10:space:>
我用你的输入执行了你的awk行。我的awk(gawk)按照您的预期输出了输出。 (单个空格分隔) – Kent 2013-05-06 13:40:30
@Kent您误解了我的问题,我问是否有办法获取第一个输出(单个输出字段分隔符=单个输入字段分隔符)。 – 2013-05-06 13:41:30
哦,对不起... .. – Kent 2013-05-06 13:45:45