1

$ 回声 "a b" | awk '{打印 $0; $1="1"; 打印 $0}' ab 1 b

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

 a       b
 1       b

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

谢谢。

4

3 回答 3

2

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

$ ... | 啊... | 列-t

将工作。(除非“我不想格式化每一列”的意思是“我不想重新格式化每一行”,例如“我不想发布流程”。在这种情况下,我会问,“为什么不呢? ")

于 2010-07-02T15:52:09.587 回答
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 的厌恶是奇怪的,只是您获得格式更改的全部原因是因为OF​​S。默认情况下,输出字段分隔符 (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 等?

于 2010-07-02T16:03:43.577 回答
1

你也可以使用替换

$ echo "a       b" | awk '{print $0; gsub("^[^ \t]","1"); print $0}'
a       b
1       b
于 2010-07-03T01:07:39.740 回答