键,值对与线上的倍数对; SED

时间:2014-09-15 23:59:57

标签: bash perl sed

假设我有一个文件在一行上有多个键,值对:

$ 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让我失望的地方)只打印一条键,每对价值对匹配?

5 个答案:

答案 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