Awk 当列被多个空格分隔时,如何更改列并保留空格?
我有一个文件,其中列由多个空格分隔 比如说,我如何设置第二列,并保持空格在同一行 例如,在postgres的pg_hba.conf中有一行Awk 当列被多个空格分隔时,如何更改列并保留空格?,awk,Awk,我有一个文件,其中列由多个空格分隔 比如说,我如何设置第二列,并保持空格在同一行 例如,在postgres的pg_hba.conf中有一行 local all all peer 如何将“对等”更改为“信任”,并保持空间在线?当我让awk执行$4=“trust”时,列之间将有一个空格。原则上这是可以的,但这会使文件更难读取,因为文件中标题的位置在行的上方。你真的不能。如果字段之间的空间大小不同。更改字段值将导致重建记录,这意味着字段分隔符FS将替换为输出字段分隔符OFS
local all all peer
如何将“对等”更改为“信任”,并保持空间在线?当我让awk执行
$4=“trust”
时,列之间将有一个空格。原则上这是可以的,但这会使文件更难读取,因为文件中标题的位置在行的上方。你真的不能。如果字段之间的空间大小不同。更改字段值将导致重建记录,这意味着字段分隔符FS
将替换为输出字段分隔符OFS
不过,您可以用正则表达式试试运气。这里有一种方法
$ echo "local all all peer" |
awk 'gsub("peer","trust")'
local all all trust
如果不是按值而是按索引更改字段,那么这里有另一种方法。例如,这次将第三个字段更改为“信任”
$ echo "local all all peer" |
awk -v RS='[^ ]+' -v ORS="" '{print $0 (NR==3?"trust":RT)}'
local all trust peer
您需要使用regexp并通过指定在进行更改之前要跳过的初始字段(
\S+
)和分隔符(\S+
)的数量对整个记录进行操作,例如使用GNU awk for gensub()和\S
/\S
:
$ awk '{$0=gensub(/(\s*(\S+\s+){3})\S+/,"\\1trust",1)}1' file
local all all trust
更改字段3是对任何潜在解决方案的更难/更好的测试,因为它的内容(all
)也出现在行的前面:
$ awk '{$0=gensub(/(\s*(\S+\s+){2})\S+/,"\\1trust",1)}1' file
local all trust peer
regexp以\s*
开头,因为默认情况下,awk忽略前导空格,但您的特定数据实际上不需要前导空格
对于其他AWK,您可以执行以下操作:
$ awk 'match($0,/[[:space:]]*([^[:space:]]+[[:space:]]+){2}/) {
head = substr($0,1,RLENGTH)
tail = substr($0,RLENGTH+1)
sub(/[^[:space:]]+/,"trust",tail)
print head tail
}' file
local all trust peer
你能举个例子来说明你在找什么吗?使用
-F'\t'
作为列分隔符,并使用$2=…
设置第二列。很抱歉,我看到这些列被多个空格分隔。但也许这并不重要。文件是postgres'pg_hba.conf,其中一行看起来像:local all peer
,如何将'peer'设置为'trust'并保持空间不变?列之间的空格数是不同的,但stackoverflow没有显示出来。当我让awk to$4=trust
时,两列之间的所有空格都会折叠成一个空格。嘿,ericj,试着在帖子中提供这些细节。它提高了对问题的理解。gawk-4.1.0:awk-v FS=“\t+”{print;printf(“[1]=%s,[2]=%s,[3]=%s\n',$1,$2,$3”);}如果不这样做,当“peer”
作为前面某列的一部分出现时,它将失败。尝试用这种方法将字段3(all
)替换为trust
。您应该提到第二种解决方案是特定于gawk的。另外,它只在只有一行输入时有效,如果字段之间有制表符则无效,如果替换第四个字段,则不会在输出末尾打印换行符。