在不破坏格式的情况下更改列的内容

时间:2010-07-02 15:44:15

标签: awk gawk

$ echo“a b”| awk'{print $ 0; $ 1 = “1”;打印$ 0}'     a b     1 b

我想接收这样的格式化输出:

 a       b
 1       b

有没有简单的方法(没有IFS,OFS更改)? 我正在改变大表中的列,然后它看起来很难看。 我不想重新格式化每一列。

感谢。

3 个答案:

答案 0 :(得分:2)

可能你最好的选择是对输出进行后期处理。也许就像这样简单:

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

会奏效。 (除非“我不想格式化每一列”意味着“我不想重新格式化每一行”,例如“我不想发布过程”。在这种情况下,我会问,“为什么不呢? “)

答案 1 :(得分:2)

一个可能的答案(假设列数固定):

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

另一个可能的答案(假设你没有充分的理由避免改变OFS,因为,你知道,这是有一个的整个要点!):

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

无论文本文件有多少列,第二个都有工作的优势。


已编辑添加:

为了解释为什么我认为你对使用OFS的厌恶是奇怪的,只是因为你获得格式化改变的全部原因是因为的OFS。输出字段分隔符(OFS)默认为单个空格。当你第一次打印$ 0时,你没有做任何修改,所以$ 0是未改变的行。通过更改您创建的其中一条记录,Awk通过从各个字段重新组合$ 0来重新评估该行。当重新组装时,当然,Awk在字段之间插入了OFS。因为那是它应该做的。引自相关手册页(man gawk):

  

为现有字段分配值会导致在引用$0时重建整个记录。   同样,为$0赋值会导致记录重新分裂,为字段创建新值。

现在我同意在第一次打印和第二次打印之间存在一些不一致,但这只是语言的方式。在您实际更改字符串之前不会插入OFS,它实际上会计算字段和重建等等。


进一步编辑添加:

观看这些:

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

Awk在你的第一个例子中的行为是否变得更清晰,以及理解为什么你真的需要OFS或printf等?

答案 2 :(得分:1)

您也可以使用替换

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