如果沒有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