Awk字段分隔符的行为

5
为什么要使用这个awk脚本:
awk '{FS = "\t" ; print $1 " - " $2}' A.txt

使用这个输入文件 A.txt
B A A1
C B A2
D A A3

输出这些结果。
B - A
C B - A2
D A - A3

请注意,第一个 B 和 A 之间有一个空格而不是制表符。我进行了双重检查。

1
awk -F "\t" '{print $1 " - " $2}' A.txt 的输出进行比较 - 所有三行的模式都是相同的。因此,您的 FS 只对 A.txt 的第一行产生影响。 - eumiro
4个回答

7

我认为这是因为FS在第一次操作中被设置了。在第一次操作被调用之前,第一行的拆分已经完成,它使用默认的FS(空格)。

所以为了保持一致,你应该使用-F选项调用awk


7
正确的方式是:
BEGIN {FS = "\t"}
{ print $1 " - " $2}  

您设置FS太晚了(在第一行被拆分后)

2

首先,您每行都在更改变量FS;您可能只想更改一次。此外,如果您确实想更改FS,则可能要在解析任何行之前更改它。 POSIX 要求对 FS 的任何更改仅影响下一行的解析。(许多实现尚未符合该要求,并且如果当前行尚未被解析,则可能会使用 FS 的更改值来处理当前行。)为解决这两个问题,您应像这样更改 FS:

awk 'BEGIN { FS="\t" } {...}' A.txt

或者这个:
awk -v 'FS=\t' '{...}' A.txt

(还有一种使用-F'\t'而不是-v'FS=\t'的表单,但是awk的某些实现不会在前一种构造中使用C-escape \t。)但请注意,FS控制输入数据的解析,而OFS控制输出数据的解析。从你的问题中并不清楚你想要做什么。乍一看,你的输入数据似乎没有任何制表符,所以你可能想让FS保持默认值“ ”。

如果你想改变输出格式,你可以将OFS设置为“\t”,以我们刚刚描述FS的任一方式。然而,这也不清楚是否是你想要的,因为你在测试脚本中没有使用OFS。当你说:

print $1 " - " $2

您正在打印一个参数,该参数是$1、" - "和$2的连接。要使用OFS,您需要打印多个参数,它们应该用逗号分隔,例如像这样:

print $1, $2

我困惑地再次查看您提供的示例数据和输出。也许您的示例数据确实具有以下格式:B<空格>A<制表符>A1,也许您确实打算设置FS以便在$1中获取B<空格>A,并在$2中获取A1。如果是这样,请确保在任何行处理开始之前正确设置FS。然后,无论您使用哪种awk实现,您的脚本都应该能够正常工作。

0
如果你在两个字符串之间不加空格,awk 就会将它们连接起来。
将命令更改为:
print $1, " - ", $2

你可能还想为输出设置OFS


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接