假设我有一个文件在一行上有多个键,值对:
$ cat test.txt
fruit: 23 oranges 55 bananas 3 peaches
candy: 16 m&m's 5 ju_ju_beans
使用Perl,在每一行上捕获多个未知数量的键值对是微不足道的:
$ perl -lane 'print "$1" while m/(\d+\s+\S+)/g' /tmp/test.txt
23 oranges
55 bananas
3 peaches
16 m&m's
5 ju_ju_beans
这可能与sed有关吗?
我试过了:
$ sed -E -n 's/(\d+\s+\S+)/$1\n/g; p' /tmp/test.txt
fruit: 23 oranges 55 bananas 3 peaches
candy: 16 m&m's 5 ju_ju_beans
但这只是打印整行。是否有可能(在某些我的谷歌foo让我失望的地方)只打印一条键,每对价值对匹配?
答案 0 :(得分:6)
grep可以单独完成:
# perl compatible regex
grep -oP '\d+\s+\S+'
# vanilla basic regex
grep -o '[[:digit:]]\+[[:blank:]]\+[^[:blank:]]\+' file
答案 1 :(得分:5)
sed
无法识别PCRE,并且使用\1
而不是$1
来调用后向引用。说过你可以尝试使用GNU sed
:
$ sed -r 's/([^[:digit:]]+)([[:digit:]]+[[:space:]]+[^[:space:]]+)/\2\n/g;' file
23 oranges
55 bananas
3 peaches
16 m&m's
5 ju_ju_beans
答案 2 :(得分:3)
这是一个简单的awk
awk '{for (i=2;i<=NF;i+=2) print $i,$(i+1)}' file
23 oranges
55 bananas
3 peaches
16 m&m's
5 ju_ju_beans
答案 3 :(得分:2)
使用sed
,我们可以使用sed '/^$/d'
删除@jaypal解决方案后的空行。
sed -r 's/([^[:digit:]]+)([[:digit:]]+[[:space:]]+[^[:space:]]+)/\2\n/g;' file | sed '/^$/d'
输出在这里。
23 oranges
55 bananas
3 peaches
16 m&m's
5 ju_ju_beans
答案 4 :(得分:0)
将regex
与GNU awk
一起使用:
gawk '{printf "%s", gensub(/([^[:digit:]]+)([[:digit:]]+[[:space:]]+[^[:space:]]+)/,"\\2\n","g")}' file
23 oranges
55 bananas
3 peaches
16 m&m's
5 ju_ju_beans
GNU awk
支持\s
,但不支持\D
或\d
。