Sed 和正则表达式,同一行上的相同模式两个不同的组?

Sed 和正则表达式,同一行上的相同模式两个不同的组?

我有一些与此类似的数据:

BLACK Harry<-George->Edna<-$$$Tom<-Tom->Phil<-Tue"

在这种情况下我想使用的数据是:

哈利<-乔治->埃德娜<-

汤姆<-汤姆->菲尔<-

我的命令目前如下所示:

sed 's!.*\(\([A-Z][a-z]*[-><][-<>]\)\{3\}\).*!\1!'

我的理解是,当我使用.*(贪婪)时,它需要最长的匹配,然后替换之前和之后的所有内容。

所以我现在的输出只是

汤姆<-汤姆->菲尔<-

如何将第一次出现的模式添加到另一个组中?

答案1

$ echo 'BLACK Harry<-George->Edna<-$$$Tom<-Tom->Phil<-Tue' |
> sed -e 's/.*\b\(\w\+<-\w\+->\w\+<-\).*\b\(\w\+<-\w\+->\w\+<-\).*/\1\n\2/'
Harry<-George->Edna<-
Tom<-Tom->Phil<-
  • \b= 字边界
  • \w= 单词字符

最好的介绍sed可以在 Bruce Barnett 的书中找到UNIX 魔法书

答案2

看起来您想要匹配字母、小于、大于、连字符,并且至少有一个连字符:

grep -Eo '[[:alpha:]<>-]+-[[:alpha:]<>-]+' <<END
BLACK Harry<-George->Edna<-$$$Tom<-Tom->Phil<-Tue"
END
Harry<-George->Edna<-
<-Tom->Phil<-Tue

答案3

echo 'BLACK Harry<-George->Edna<-$$$Tom<-Tom->Phil<-Tue' |
sed -r '
s/(\b\w+<-\w+->\w+<-)([^\n])/\1\n\2/g  # seperate matchs with \n
s/.+(\b\w+<-\w+->\w+<-)/\1/Mg          # remove the front in each lines
/\b\w+<-\w+->\w+<-$/!s/[\n]?[^\n]*$//' # remove the last unmatch line if exist

相关内容