【问题标题】:Find and replace with same wildcard查找并替换为相同的通配符
【发布时间】:2019-12-27 17:32:57
【问题描述】:

我想用通配符搜索并用相同的通配符替换。例如搜索特定的水果名称并将其替换为不同位置的相同名称。

输入:

fruit_id "Apple"; salad_id ""; 
fruit_id "Mango"; salad_id "";
fruit_id "Kiwi"; salad_id ""; 

预期输出:

fruit_id "Apple"; salad_id "Apple"; 
fruit_id "Mango"; salad_id "Mango";
fruit_id "Kiwi"; salad_id "Kiwi";

我正在使用 sed,但显然它不起作用:

sed 's/fruit_id "..*"; salad_id "";/fruit_id "..*"; salad_id "..*";/g'

【问题讨论】:

  • awk '$4=$2' FS='"' OFS='"' file

标签: sed replace


【解决方案1】:

您可以捕获部分并在替换中使用占位符来引用捕获的值:

sed 's/\(fruit_id "\([^"]*\)"; salad_id \)"";/\1"\2";/g' file > newfile

详情

  • \(fruit_id "\([^"]*\)"; salad_id \) - 第 1 组 (\1):
    • fruit_id " - fruit_id " 子字符串
    • \([^"]*\) - 第 2 组 (\2):除 " 之外的任何 0+ 个字符
    • "; salad_id - "; salad_id 子字符串
  • ""; - ""; 子字符串。

online demo

s='fruit_id "Apple"; salad_id ""; 
fruit_id "Mango"; salad_id "";
fruit_id "Kiwi"; salad_id "";'

sed 's/\(fruit_id "\([^"]*\)"; salad_id \)"";/\1"\2";/g' <<< "$s"

输出:

fruit_id "Apple"; salad_id "Apple"; 
fruit_id "Mango"; salad_id "Mango";
fruit_id "Kiwi"; salad_id "Kiwi";

【讨论】:

  • 我认为使用 2 个捕获组既无用也无效率。一个就够了,看我的回答。
  • @CCH 你的sed 's/fruit_id "([^"]*)"; salad_id "";/fruit_id "\1"; salad_id "\1";/g' 答案是错误的,使用两个组会使正则表达式更短,保持性能几乎相同。
  • 谢谢我修正了我的答案。我仍然认为只使用一个组对于捕获组的新手来说更具可读性。
  • @CCH 这是你的意见。它与解决方案的正确性无关。
  • @kashiff007 它在"([^"]*)" 匹配" 时效果很好,然后将" 以外的*0 个或更多* 字符捕获到第1 组,然后匹配"
【解决方案2】:

试试这个:

sed 's/fruit_id "\([^"]*\)"; salad_id "";/fruit_id "\1"; salad_id "\1";/g'

想法是使用带括号的捕获组,然后使用\1重新使用捕获的文本

有关您的示例的详细说明,请参阅此工具: https://regex101.com/r/N4sfGA/1

【讨论】:

  • 你的 sed 命令fails to work。 Regex101 不支持 POSIX BRE 语法,您应该小心使用 sed 中测试的模式。
  • 你说得对,谢谢,我修正了括号的转义。
  • 不过,使用这种冗长的替换模式没有任何意义,您可以通过两个反向引用使其更短。见my answer。捕获组正是为此:重新插入我们需要保留在结果字符串中的匹配部分。
【解决方案3】:

awk 解决方案

awk '{$4=$2}1' FS='"' OFS='"' file
fruit_id "Apple"; salad_id "Apple";
fruit_id "Mango"; salad_id "Mango";
fruit_id "Kiwi"; salad_id "Kiwi";

通过"拆分数据,然后将数据从第二个字段复制到第四个字段。

【讨论】:

    猜你喜欢
    • 2017-04-23
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    • 2018-07-04
    • 2017-03-11
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    相关资源
    最近更新 更多