我的文件中有以逗号分隔的行。没有列标题,主要是逗号分隔的“名称=值”对。以下是一些测试数据:
listoffruits,producelist,APPLE=red,BANNANA=yellow,GRAPE=purple,ORANGE=orange,FRUIT=yes,WATERMELON=green
listoffruits,producelist,APPLE=red,BANNANA=yellow,GRAPE=violet,ORANGE=orange,FRUIT=affirmative,WATERMELON=green
我想获取 GRAPE=* 和 FRUIT=* 的值以获得结果:
purple yes
violet affirmative
此外,我希望以后能够添加更多“列”(因此不总是葡萄、水果,而是葡萄、水果和西瓜)
另一个障碍是柱子不是固定的。所以我并不总是知道西瓜是最后一栏。
我得到的最接近的是来自@jasonwryan:
awk -v RS="," -F= '/GRAPE/{a=$2}; /FRUIT/{b=$2} END{print a,b"\n"}'
但这输出最后一行“紫罗兰肯定”而不是:
purple yes
violet affirmative
答案1
多一些选择。为了简单起见,我已保存您的示例文本file
。
grep
和 PCRE:$ grep -oP '(GRAPE|FRUIT)=\K.*?(?=,)' file purple yes violet affirmative
为了让它们在同一行,只需解析即可。例如
$ grep -oP '(GRAPE|FRUIT)=\K.*?(?=,)' | paste -d" " - - – purple yes violet affirmative
sed
$ sed 's/.*GRAPE=\([^,]*\).*FRUIT=\([^,]*\).*/\1 \2/' file purple yes violet affirmative
或者,使用 GNU
sed
$ sed -r 's/.*GRAPE=([^,]*).*FRUIT=([^,]*).*/\1 \2/' file purple yes violet affirmative
Perl
$ perl -pne 's/.*GRAPE=([^,]*).*FRUIT=([^,]*).*/\1 \2/' file purple yes
您可能会注意到上面的内容与上面的内容略有相似
sed
:)。或者:$ perl -lne '@f=(/(?:(?<=GRAPE=)|(?<=FRUIT=))(.+?),/g); print "@f"' file purple yes violet affirmative
这用作
,
字段分隔符并搜索所有字段:$ perl -F, -lane '@r=grep(s/.+?=//, grep(/GRAPE|FRUIT/,@F)); print "@r"' file purple yes violet affirmative
这个较短,但为每行添加了一个前导空格:
$ perl -F, -lane 'print grep(s/.+?=/ /, grep(/GRAPE|FRUIT/,@F));' file purple yes violet affirmative
答案2
使用awk:
awk -v RS="," -F= '/GRAPE/||/FRUIT/ {printf "%s ", $2}'
将记录分隔符从换行更改为,,
将字段分隔符从空格更改为=
,然后匹配包含模式的行GRAPE
或FRUIT
并在同一行上打印第二个匹配字段,并以空格分隔。结果:
purple yes