awk - 理解 FS 是如何工作的
awk - understanding how FS works
我知道默认的 FS= " ",那为什么我在以下 awk 命令中看到变化。请帮助我理解。
>echo " ABC DEF XYZ \n abc def,ghi xyz \n" | awk '{printf("nf: %s 1:%s line: %s\n", NF, , [=10=])}'
nf: 3 1:ABC line: ABC DEF XYZ
nf: 3 1:abc line: abc def,ghi xyz
nf: 0 1: line:
>echo " ABC DEF XYZ \n abc def,ghi xyz \n" | awk -F" " '{printf("nf: %s 1:%s line: %s\n", NF, , [=10=])}'
nf: 3 1:ABC line: ABC DEF XYZ
nf: 3 1:abc line: abc def,ghi xyz
nf: 0 1: line:
>echo " ABC DEF XYZ \n abc def,ghi xyz \n" | awk -F"[ ]" '{printf("nf: %s 1:%s line: %s\n", NF, , [=10=])}'
nf: 10 1: line: ABC DEF XYZ
nf: 17 1: line: abc def,ghi xyz
nf: 0 1: line:
>echo " ABC DEF XYZ \n abc def,ghi xyz \n" | awk -F"[ ]*" '{printf("nf: %s 1:%s line: %s\n", NF, , [=10=])}'
nf: 5 1: line: ABC DEF XYZ
nf: 5 1: line: abc def,ghi xyz
nf: 0 1: line:
我想了解为什么在第一个和第二个示例中没有空标记,但在第三个和第四个示例中存在。
更新:为了进一步解释我的疑问,awk 与默认 FS 和自定义 FS 的行为不一致。请参阅以下示例。
>printf "ab cd\nef gh\n" | awk -F" " '{ printf("nf: %d\t", NF); for (i=1;i<=NF;i++) printf("%02d:%s\t", i, $i); print ""}'
nf: 2 01:ab 02:cd
nf: 2 01:ef 02:gh
>printf "ab::cd\nef:gh\n" | awk -F":" '{ printf("nf: %d\t", NF); for (i=1;i<=NF;i++) printf("%02d:%s\t", i, $i); print ""}'
nf: 3 01:ab 02: 03:cd
nf: 2 01:ef 02:gh
默认情况下 awk
使用单个 space 作为默认值 FS
。这是一个特例,也是唯一的特例。两个或多个 space 不被解释为多个字段,而是被解释为单个分隔符。使用 任何其他字符 会导致该字符的每次出现都被解释为分隔符。所以使用 ':'
会将 ":::my"
解释为四个字段。 (empty
、empty
、empty
、"my"
)参见:GNU Awk User's Guide - 4.5.1 Whitespace Normally Separates Fields.
当您使用 正则表达式 时,每个出现的 FS
字符(即使是 space)都被视为单独的字段分隔符。参见 GNU Awk User's Guide - 4.5.2 Using Regular Expressions to Separate Fields。
要将每个字符作为一个单独的字段进行检查,您只需将 FS
设置为 empty-string(空),在命令行中使用 -F""
或设置 FS = ""
.
在您使用正则表达式 -F"[ ]"
的示例中,每个 space 都被视为一个单独的字段分隔符。 FS
是正则表达式而不是默认大小写。这是一个正则表达式,其中单个字符恰好是 space.
随着 *
(zero-or-more) 次的重复出现,FS
有点模棱两可。它可以不匹配任何内容 (null),也可以匹配一行中尽可能多的 space。 (这就是为什么它匹配第一个字符然后匹配多个 spaces)我不建议以这种方式弄乱 spaces 和 FS
。
awk
理解 扩展正则表达式 (ERE) 语法,因此您可以对 [=67 使用 '+'
重复说明符=] 个字符。
将 GNU Awk User's Guide 放在手边。它是 gawk
以及 awk
其他风格的一个很好的参考。在指南中如果某些东西是gawk
独有的,它会在指南中用'#'
标记来告诉你。它通常解释(有时在脚注中)gawk
行为与 POSIX、awk
或 mawk
等有何不同。
我知道默认的 FS= " ",那为什么我在以下 awk 命令中看到变化。请帮助我理解。
>echo " ABC DEF XYZ \n abc def,ghi xyz \n" | awk '{printf("nf: %s 1:%s line: %s\n", NF, , [=10=])}'
nf: 3 1:ABC line: ABC DEF XYZ
nf: 3 1:abc line: abc def,ghi xyz
nf: 0 1: line:
>echo " ABC DEF XYZ \n abc def,ghi xyz \n" | awk -F" " '{printf("nf: %s 1:%s line: %s\n", NF, , [=10=])}'
nf: 3 1:ABC line: ABC DEF XYZ
nf: 3 1:abc line: abc def,ghi xyz
nf: 0 1: line:
>echo " ABC DEF XYZ \n abc def,ghi xyz \n" | awk -F"[ ]" '{printf("nf: %s 1:%s line: %s\n", NF, , [=10=])}'
nf: 10 1: line: ABC DEF XYZ
nf: 17 1: line: abc def,ghi xyz
nf: 0 1: line:
>echo " ABC DEF XYZ \n abc def,ghi xyz \n" | awk -F"[ ]*" '{printf("nf: %s 1:%s line: %s\n", NF, , [=10=])}'
nf: 5 1: line: ABC DEF XYZ
nf: 5 1: line: abc def,ghi xyz
nf: 0 1: line:
我想了解为什么在第一个和第二个示例中没有空标记,但在第三个和第四个示例中存在。
更新:为了进一步解释我的疑问,awk 与默认 FS 和自定义 FS 的行为不一致。请参阅以下示例。
>printf "ab cd\nef gh\n" | awk -F" " '{ printf("nf: %d\t", NF); for (i=1;i<=NF;i++) printf("%02d:%s\t", i, $i); print ""}'
nf: 2 01:ab 02:cd
nf: 2 01:ef 02:gh
>printf "ab::cd\nef:gh\n" | awk -F":" '{ printf("nf: %d\t", NF); for (i=1;i<=NF;i++) printf("%02d:%s\t", i, $i); print ""}'
nf: 3 01:ab 02: 03:cd
nf: 2 01:ef 02:gh
默认情况下 awk
使用单个 space 作为默认值 FS
。这是一个特例,也是唯一的特例。两个或多个 space 不被解释为多个字段,而是被解释为单个分隔符。使用 任何其他字符 会导致该字符的每次出现都被解释为分隔符。所以使用 ':'
会将 ":::my"
解释为四个字段。 (empty
、empty
、empty
、"my"
)参见:GNU Awk User's Guide - 4.5.1 Whitespace Normally Separates Fields.
当您使用 正则表达式 时,每个出现的 FS
字符(即使是 space)都被视为单独的字段分隔符。参见 GNU Awk User's Guide - 4.5.2 Using Regular Expressions to Separate Fields。
要将每个字符作为一个单独的字段进行检查,您只需将 FS
设置为 empty-string(空),在命令行中使用 -F""
或设置 FS = ""
.
在您使用正则表达式 -F"[ ]"
的示例中,每个 space 都被视为一个单独的字段分隔符。 FS
是正则表达式而不是默认大小写。这是一个正则表达式,其中单个字符恰好是 space.
随着 *
(zero-or-more) 次的重复出现,FS
有点模棱两可。它可以不匹配任何内容 (null),也可以匹配一行中尽可能多的 space。 (这就是为什么它匹配第一个字符然后匹配多个 spaces)我不建议以这种方式弄乱 spaces 和 FS
。
awk
理解 扩展正则表达式 (ERE) 语法,因此您可以对 [=67 使用 '+'
重复说明符=] 个字符。
将 GNU Awk User's Guide 放在手边。它是 gawk
以及 awk
其他风格的一个很好的参考。在指南中如果某些东西是gawk
独有的,它会在指南中用'#'
标记来告诉你。它通常解释(有时在脚注中)gawk
行为与 POSIX、awk
或 mawk
等有何不同。