GAWK 将 FS 计为字段

GAWK is counting FS as fields

我想解析以下文本,使每一行包含一个字段(所有文本不包括标签):

<tag>first line</tag>
<tag>second line</tag>

为此,我使用了这个 GAWK 脚本:

BEGIN{FS="</?tag>";}
    {for (i=1; i<=NF; i++){print "field " i "->" $i;}}
END{}

我期待这个输出:

field 1->first line
field 1->second line

相反,我得到了这个:

field 1->
field 2->first line
field 3->
field 1->
field 2->second line
field 3->

有人可以解释在字段 $1 和 $3 下捕获的内容吗?我也尝试过使用 FS="</?tag>\n?",但我得到了相同的输出。

给定 FS 的值,对于 Awk,行 <tag>first line</tag> 看起来像这样:

field1 delimiter field2 delimiter field3

一个简单的解决方法是放弃循环,并简单地打印 </code>,如果你知道每行只会有一个 "field":</p> <pre><code>BEGIN {FS = "</?tag>"} {print }

给定此文件 FS=","

a,b,c

字段 1 中有什么?是 "a",对吧?

现在给这个文件 FS="</?tag>":

a<tag>b</tag>c

字段 1 中有什么?还是"a".

现在给定这个文件FS="</?tag>":

<tag>b</tag>c

字段 1 中有什么?现在是空字符串 ("").

现在给定这个文件FS="</?tag>":

<tag>first line</tag>

字段 1 中有什么?字段 3 仍然 "" 和同上。

作为 ,只是 print ,或者如果您真正想要的是仅使用 </tag> 作为 FS,但从每个字段中删除相关的前导 <tag>那就是:

$ awk -v FS='</tag>' '{ for (i=1; i<=NF; i++) if (sub(/.*<tag>/,"",$i)) print i, $i }' file
1 first line
1 second line

当一行中有多个字段时,可以说它具有更直观的行为:

$ cat file
<tag>line 1, field 1</tag><tag>line 1, field 2</tag>
<tag>line 2, field 1</tag><tag>line 2, field 2</tag><tag>line 2, field 3</tag>

$ awk -v FS='</tag>' '{ for (i=1; i<=NF; i++) if (sub(/.*<tag>/,"",$i)) print NR, NF, i, $i; print "" }' file
1 3 1 line 1, field 1
1 3 2 line 1, field 2

2 4 1 line 2, field 1
2 4 2 line 2, field 2
2 4 3 line 2, field 3

$ awk -v FS='</?tag>' '{ for (i=1; i<=NF; i++) print NR, NF, i, $i; print "" }' file
1 5 1
1 5 2 line 1, field 1
1 5 3
1 5 4 line 1, field 2
1 5 5

2 7 1
2 7 2 line 2, field 1
2 7 3
2 7 4 line 2, field 2
2 7 5
2 7 6 line 2, field 3
2 7 7

$ awk -v FS='</?tag>' '{ for (i=2; i<=NF; i+=2) print NR, NF, i, $i; print "" }' file
1 5 2 line 1, field 1
1 5 4 line 1, field 2

2 7 2 line 2, field 1
2 7 4 line 2, field 2
2 7 6 line 2, field 3