grep 精确匹配字符串的两个部分

grep 精确匹配字符串的两个部分

如何使用 grep 命令获取如下字符串的一部分?

细绳:

orange:"orange", red:"apple", purple:"grape", yellow:"banana", green:"watermelon"
red:"strawberries", yellow:"lemon"

我想要的是:

red:"apple" yellow:"banana"
red:"strawberries" yellow:"lemon"

我已经尝试过这个:

grep -oP '(red:\"[^\"]*).*(yellow:\"[^\"]*)'

答案1

中间.*的匹配所有内容,即purple:"grape"部分。相反(假设您想坚持使用 GNU grep),我将使用(foo|bar)“OR”结构分别匹配每个部分。

grep -oP '(red|yellow):\"[^\"]*"'

注意我必须添加结束语"。另外,您不需要转义",因此您可以使用

grep -oP '(red|yellow):"[^"]*"'

无论如何,这给你

red:"apple"
yellow:"banana"

然后将线条连接起来,线条之间留有空间,

grep -oP '(red|yellow):"[^"]*"' | paste -sd ' ' -

老实说,我自然会用sed它来代替。

sed -n 's/.*\(red:"[^"]*"\).*\(yellow:"[^"]*"\).*/\1 \2/p'

答案2

grep通常不会离线提取内容。它打印与常规表达式p匹配的行(一般来说,它以命令命名)。regg/re/p ed

然而,一些实现(例如grep您似乎正在使用的 GNU)需要-o将其中的一些功能作为扩展。

pcregrep甚至更进一步。它-o可以采用可选的数字参数来输出捕获组的内容,而不是行的整个匹配部分。

pcregrep -o1 -o2 --om-separator=' ' '(red:"[^"]*").*(yellow:"[^"]*")'

它能做的事情仍然有限。

要从行中提取信息并进行更多转换,您需要使用文本sed,而不是像其他人在此处所示的那样。

答案3

grep你确实可以这样做由斯帕霍克建议,或者几乎相同:

$  echo 'red:"apple", purple:"grape", yellow:"banana"' |      
        grep -oP '(red|yellow):".+?"' | perl -00pe 's/\n/ /'
red:"apple" yellow:"banana"

就我个人而言,我可能会这样做perl

$ echo 'red:"apple", purple:"grape", yellow:"banana"' | 
    perl -F, -ane 'map{print if /red|yellow/}@F'
red:"apple" yellow:"banana"

相关内容