如何在BASH中替换匹配`{+(anything)+}`与`{+(anything)+ :: +(anything)+}`的模式?

时间:2014-05-20 04:29:02

标签: bash sed

我有一个带有文字的文件,其中一些重要的项目标有开始和结束括号,例如:

Once upon a {time}, there lived a rabbit.
The {rabbit lived} in a small house.
One day, the {rabbit visited }the {mountains}.
In the mountains, he {found} a tree with 10{,000} branches.

我需要将{x}表单中的所有项目替换为{x::x},例如:

Once upon a {time::time}, there lived a rabbit.
The {rabbit lived::rabbit lived} in a small house.
One day, the {rabbit visited ::rabbit visited }the {mountains::mountains}.
In the mountains, he {found::found} a tree with 10{,000::,000} branches.
  • 每个开头{在同一行都有匹配的}
  • 大括号永远不会分开。
  • 大括号永远不会嵌套。
  • {}之间可能会出现任何类型的符号。

我尝试了sed的几种方法,但没有任何效果,例如:

sed 's/{(.*)}/{&::&}/g' file.txt

如何更换大括号中的所有项目,例如{some word}模式为{some word::some word}

4 个答案:

答案 0 :(得分:4)

这是修复

sed 's/{\([^}]*\)}/{\1::\1}/g' file

Once upon a {time::time}, there lived a rabbit.
The {rabbit lived::rabbit lived} in a small house.
One day, the {rabbit visited ::rabbit visited }the {mountains::mountains}.
In the mountains, he {found::found} a tree with 10{,000::,000} branches.

解释

  • [^}]*匹配非}字符
  • \(...\)将捕获在parens中指定的字符,\ 1将用于引用第一个匹配,这是正则表达式的一部分。

答案 1 :(得分:2)

如果您可以使用perl

,则会更容易
$ perl -ple 's/{(.*?)}/{$1::$1}/g' file
Once upon a {time::time}, there lived a rabbit.
The {rabbit lived::rabbit lived} in a small house.
One day, the {rabbit visited ::rabbit visited }the {mountains::mountains}.
In the mountains, he {found::found} a tree with 10{,000::,000} branches.

它匹配大括号{...} 非贪婪中的所有内容,然后将其替换为所需的字符串{$1::$1}

答案 2 :(得分:1)

你应该使用

sed 's/\([^{]*{\)\([^}]*\)\(}.*\)/\1\2::\2\3/'

未经测试

答案 3 :(得分:1)

awk变体:

$ awk 'BEGIN{ORS=""} NR%2==0{$0="{"$0"::"$0"}"} 1' RS='[{}]' file.txt

Once upon a {time::time}, there lived a rabbit.
The {rabbit lived::rabbit lived} in a small house.
One day, the {rabbit visited ::rabbit visited }the {mountains::mountains}.
In the mountains, he {found::found} a tree with 10{,000::,000} branches.