awk字段分隔符对于第一行不起作用

15
echo 'NODE_1_length_317516_cov_18.568_ID_4005' | awk 'FS="_length" {print $1}'

获得的输出:

NODE_1_length_317516_cov_18.568_ID_4005

预期输出:

NODE_1

怎么可能呢?我漏掉了什么。

3个回答

21

当您使用Awk逐行处理时,字段分隔符会在处理记录之前进行解释。 Awk根据当前的FSRS值读取记录,并继续执行您要求的操作。

这意味着如果您设置FS的值来读取记录,对于该特定记录,它不会产生影响。相反,FS将在读取下一条记录时产生影响,并且以此类推。

因此,如果您有一个文件如下:

$ cat file
1,2 3,4
5,6 7,8

如果您在读取一行记录时设置了字段分隔符,它将从下一行开始生效:

$ awk '{FS=","} {print $1}' file
1,2                             # FS is still the space!
5

所以您想要做的是在开始读取文件之前设置FS。也就是说,在BEGIN块中或通过参数设置:

$ awk 'BEGIN{FS=","} {print $1}' file
1,2                             # now, FS is the comma
5
$ awk -F, '{print $1}' file
1
5

还有另一种方法:使用{$0=$0}让Awk重新计算完整记录。这样,Awk将考虑当前的FS并相应地执行:

另外还有一种方法:用{$0=$0}让Awk重新计算完整记录。这样,Awk会考虑当前的FS并相应地执行:

(Two possible translations with minor differences in wording.)
$ awk '{FS=","} {$0=$0;print $1}' file
1
5

假设我的第一行是 Cal_Tno_V19_F04_R02。如何使用 awk 打印 Cal_Tno,即打印前两个字段和分隔符? - Sigur
@Sigur,这似乎是一个完全不同的问题,与我在此回答的问题不同。最好您提供足够的细节提出新问题 - fedorqui

2

awk语句使用不正确

正确的方式是:

awk 'BEGIN { FS = "#{delimiter}" } ; { print $1 }'

在您的情况下,您可以使用:
awk 'BEGIN { FS = "_length" } ; { print $1 }'

提醒一下,如果您尝试使用 print $0,它将生成在应用字段分隔符之前的原始行。要打印具有新FS的整行,您必须循环遍历字段并打印或使用分配字段的快捷方式,该快捷方式重新计算带有FS的行:{ $1 = $1; print $0} - Merlin

0
内置变量如FS、ORS等必须在上下文中设置,即在以下块之一中:BEGIN、条件块或END。
$ echo 'NODE_1_length_317516_cov_18.568_ID_4005' | awk 'BEGIN{FS="_length"} {print $1}'
NODE_1
$

您还可以使用-F开关来传递分隔符,就像这样:
$ echo 'NODE_1_length_317516_cov_18.568_ID_4005' | awk -F "_length" '{print $1}'
NODE_1
$

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