当列由多个空格分隔时,如何更改列并保留空格?

时间:2016-08-09 08:46:58

标签: awk

我有一个文件,其中列由多个空格分隔。

如何设置,让我们说第二列,并保留空格?

例如,在postgres' pg_hba.conf有一行

local  all   all          peer

我怎样才能改变同伴'信任'并保持他们在线上的空间?当我让awk做$4="trust"时,列之间会有一个空格。原则上可以,但它会使文件更难阅读,因为文件中行的标题位置。

3 个答案:

答案 0 :(得分:1)

这是一种方法

$ echo "local  all   all          peer" | 
  awk 'gsub("peer","trust")'

local  all   all          trust

如果您不是按值而是按索引更改字段,这是另一种方法。例如,将第三个字段更改为" trust"这一次

$ echo "local  all   all          peer" | 
  awk -v RS='[^ ]+' -v ORS="" '{print $0 (NR==3?"trust":RT)}'

local  all   trust          peer

答案 1 :(得分:1)

您需要使用正则表达式并对整个记录进行操作,方法是在进行更改之前指定要跳过的初始字段(\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

正则表达式以\s*开头,因为默认情况下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

答案 2 :(得分:0)

你真的不能。如果字段之间的空间量不同。更改字段值将导致重建记录,这意味着字段分隔符FS将替换为输出字段分隔符OFS

你可以尝试使用正则表达式来运气。