GAWK将FS计为字段

时间:2017-03-11 13:07:01

标签: regex awk gawk

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

<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?",但我得到了相同的输出。

2 个答案:

答案 0 :(得分:1)

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

field1 delimiter field2 delimiter field3

一个简单的解决方法是放弃循环,只需打印$2,如果您知道只有一个&#34;字段&#34;每行:

BEGIN {FS = "</?tag>"} {print $2}

答案 1 :(得分:0)

鉴于此文件为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场。

@janos said,只是print $2,或者如果您真正想要的是仅使用</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