开发者

changing content of the column without destroying formating

$ echo "a b" | awk '{print $0; $1="1"; print $0}' a b 1 b

I would like to receive formatted output like this:

 a       开发者_JAVA百科b
 1       b

Is there easy way to do that (without IFS,OFS changes)? I am changing columns in big table and afterwards it looks ugly. I don't want to reformat each column.

Thanks.


Probably your best bet is to post-process the output. Perhaps something as simple as:

$ ... | awk ... | column -t

will work. (Unless by "I don't want to format each column" means "I don't want to reformat each row", eg "I don't want to post process". In which case I would ask, "Why not?")


One possible answer (assuming a fixed number of columns):

echo "a       b" | awk '{print $0; $1="1"; printf("%s\t%s\n", $1, $2)}'

Another possible answer (assuming you don't have a good reason to avoid changing the OFS since, you know, that's the whole POINT of having one!):

echo "a       b" | awk 'BEGIN { OFS="\t" } {print $0; $1="1"; print $0}'

This second one has the advantage of working no matter how many columns your text file has.


Edited to add:

To explain why I think your aversion to using the OFS is bizarre, it's just that the whole reason you're getting that formatting change is because of the OFS. The Output Field Separator (OFS) is by default a single space. When you printed $0 the first time, you'd not made any modifications so $0 was the unaltered line. By changing one of the records you made Awk reassess the line by reassembling $0 from the individual fields. Upon reassembling this, of course, Awk inserted the OFS between fields. Because that's what it's supposed to do. Quote from the relevant man page (man gawk):

Assigning a value to an existing field causes the whole record to be rebuilt when $0 is referenced. Similarly, assigning a value to $0 causes the record to be resplit, creating new values for the fields.

Now I agree that there's a bit of an inconsistency between having the first print and the second treat the fields differently, but that's just the way the language is. The OFS isn't inserted until you actually change the string and it actually calculates the fields and rebuilds and so forth.


Further edited to add:

Watch these:

$ awk 'BEGIN { printf("|%s|\n", OFS) }'
| |
$ awk 'BEGIN { OFS="\t" ; printf("|%s|\n", OFS) }'
|   |
$ 

Is the behaviour of Awk in your first example becoming clearer, as well as understanding why you actually need that OFS or a printf or the like?


you can also use substitution

$ echo "a       b" | awk '{print $0; gsub("^[^ \t]","1"); print $0}'
a       b
1       b
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜