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
我想解析以下文本,使每一行包含一个字段(所有文本不包括标签):
<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