首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >条件sed取决于相同或不相同的反向引用

条件sed取决于相同或不相同的反向引用
EN

Stack Overflow用户
提问于 2020-12-08 16:27:15
回答 2查看 99关注 0票数 0

以下sed命令:

代码语言:javascript
运行
复制
sed -E -e 's#µ(bar)>([^|¢]+)\|([^µ|]+)¢#:\1:`\3 <\2>`#g'

:\1:`\3 <\2>`

  • 接受µ¢之间的内容,

  • 将其拆分为3个反向引用(\1\2\3),其中>|作为分隔符,H 213H 114并返回

例如:

代码语言:javascript
运行
复制
$ sed -E -e 's#µ(bar)>([^|¢]+)\|([^µ|]+)¢#:\1:`\3 <\2>`#g' <<< "µbar>foo|baz¢"
:bar:`baz <foo>`
$ sed -E -e 's#µ(bar)>([^|¢]+)\|([^µ|]+)¢#:\1:`\3 <\2>`#g' <<< "µbar>foo|foo¢"
:bar:`foo <foo>`

现在,我想只返回:\1:`\2`,在\3\2是相同的情况下,以便在第二个示例中得到:bar:`foo`

如何使用sed (可能在另一个工具的帮助下)实现这一结果?

编辑1

更广泛地说,我的实际用例涉及备选方案,例如以下选项(只有第一个用例需要以反向引用为条件):

代码语言:javascript
运行
复制
sed -E -e 's#µ(bar1|bar2|bar3)>([^|¢]+)\|([^µ|]+)¢#:\1:`\3 <\2>`#g ; s#µ(bar1|bar2|bar3)>([^|¢µ]+)¢#:\1:`\2`#g'

@anubhava对我的第一个问题的第一个回答是基于awk的,它的语法对我来说非常深奥:)

编辑2

在我最初的问题中,第一个组不应该匹配([^...])分隔符(µ|µ),以便处理同一行上多次出现的模式。备注:图案可能被文字包围,特别是可能不在行首。

此外,我还必须处理没有|分隔符的情况(我的编辑1的第二个sed命令),例如µbar3>foo¢应该返回:bar3:`foo`

因此,一个更真实的测试文件应该是:

代码语言:javascript
运行
复制
Bla bla bla µbar1>foo|baz¢ bla bla bla µbar2>foo|foo¢ bla bla bla.
Bla bla bla µbar3>foo¢ bla bla bla.

预期产出如下:

代码语言:javascript
运行
复制
Bla bla bla :bar1:`baz <foo>` bla bla bla :bar2:`foo` bla bla bla.
Bla bla bla :bar3:`foo` bla bla bla.
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-12-09 03:17:52

如果Perl是您的选择,请您尝试以下方法:

代码语言:javascript
运行
复制
perl -pe 's#μ(.+?)>(.+?)(?:\|(.+?))?¢#
    sprintf(":%s:`%s`", $1, ($3 eq "" or $2 eq $3) ? $2 : "$3 <$2>") #ge' < input.txt

input.txt

代码语言:javascript
运行
复制
μbar>foo|baz¢
μbar>foo|foo¢
μbar>foo¢
Bla bla bla μbar1>foo|baz¢ bla bla bla μbar2>foo|foo¢ bla bla bla.
Bla bla bla μbar3>foo¢ bla bla bla.

输出:

代码语言:javascript
运行
复制
:bar:`baz <foo>`
:bar:`foo`
:bar:`foo`
Bla bla bla :bar1:`baz <foo>` bla bla bla :bar2:`foo` bla bla bla.
Bla bla bla :bar3:`foo` bla bla bla.

delimiters.

  • The
  • -pe选项告诉Perl逐行处理输入文件,然后像sed -e那样打印每一行。regex .+?与子字符串匹配尽可能短,如果输入行包含多个overrun regex (?:pattern)类似于分组(pattern),但它不创建用于反向引用的捕获组,则不必关心overrun。(这意味着regex最多生成从$1$3的反折射,而不是对regex的$1 g选项启用全局(多个)匹配。
  • e选项允许替换不仅是字符串,而且是perl表达式。这是一个强大的特性,可以使替换变得非常灵活(希望readable).
  • The表达式($3 eq "" or $2 eq $3) ? $2 : "$3 <$2>"看起来很模糊,但它只是一个条件运算符,意思是如果$3为空或$2和$3相同,则打印$2,否则打印"$3 <$2>“。

)

票数 3
EN

Stack Overflow用户

发布于 2020-12-08 16:44:54

现在,我想要的是只返回

\2相同的情况下的:\1:`\2`

在这里使用awk更容易,如下所示:

代码语言:javascript
运行
复制
cat file
µbar>foo|baz¢
µbar>foo|foo¢

awk命令:

代码语言:javascript
运行
复制
awk -F '[|>]+' '$1 ~ /^µ(bar1|bar2|bar3)$/ {
   sub(/¢$/, "", $3)
   print ":" substr($1, 2) ":`" ($2 != $3 ? $2 " " : "") "<" $3 ">`"
}' file

:bar:`foo <baz>`
:bar:`<foo>`

由于问题在这里发布后已被大量修改,所以需要一个gnu-awk来获得预期的输出:

代码语言:javascript
运行
复制
awk '{
   while (match($0, /µ(bar1|bar2|bar3)>([^|¢]+)(\|([^µ|]+))?¢/, m)) { 
      printf "%s", substr($0, 1, RSTART-1) ":" m[1] ":`" (m[4] != "" ? m[4] (m[2] != m[4] ? " <" m[2] ">" : "") : m[2]) "`"
      $0 = substr($0, RSTART+RLENGTH)
   }
   print ""
}' file

Bla bla bla :bar1:`baz <foo>` bla bla bla :bar2:`foo`
Bla bla bla :bar3:`foo`
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65202868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档