Reputation: 2291
I have a file where the columns are seperated by multiple spaces.
How can I set, let's say, the second column, and keep the spaces on the line?
For example, in postgres' pg_hba.conf there is a line
local all all peer
How can I change 'peer' to 'trust' and keep the spaces as they are on the line? When I let awk do $4="trust"
there will be one space between the columns. In principle that is OK, but it makes the file harder to read, because of the position of headers above the line in the file.
Upvotes: 1
Views: 231
Reputation: 203169
You need to use a regexp and operate on the whole record by specifying how many initial fields (\S+
) plus separators (\s+
) to skip before making your change, e.g. with GNU awk for gensub() and \s
/\S
:
$ awk '{$0=gensub(/(\s*(\S+\s+){3})\S+/,"\\1trust",1)}1' file
local all all trust
Changing field 3 is a harder/better test of any potential solution since it's contents (all
) appear earlier in the line too:
$ awk '{$0=gensub(/(\s*(\S+\s+){2})\S+/,"\\1trust",1)}1' file
local all trust peer
The regexp starts with \s*
since by default awk ignores leading white space but that's not actually needed for your specific data.
With other awks you'd do:
$ 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
Upvotes: 1
Reputation: 67467
here is one approach
$ echo "local all all peer" |
awk 'gsub("peer","trust")'
local all all trust
here is another approach if you're changing the field not by value but by index. For example change third field to "trust" this time
$ echo "local all all peer" |
awk -v RS='[^ ]+' -v ORS="" '{print $0 (NR==3?"trust":RT)}'
local all trust peer
Upvotes: 1
Reputation: 37394
You really can't. If the amount of space varies between fields. Changing a field value will lead to rebuilding the record which means that the field separator FS
is replaced by output field separator OFS
.
You can try your luck with regex, though.
Upvotes: 0