如何替换括号内的一个字符保留其他所有字符

时间:2017-11-02 20:00:20

标签: awk sed grep

数据如下所示:

There is stuff here (word, word number phrases)
(word number anything, word phrases), even more
...

在不同的文件中有很多。还有不同类型的数据,它们周围都没有相同的格式。对象内的数据不会改变,而且它总是在同一条线上。我没有必要处理:

(stuff number,
maybe more here)

我希望能够用冒号替换逗号

所需的输出将是

There is stuff here (word: word number phrases)
(word number anything: word phrases), even more
...

5 个答案:

答案 0 :(得分:4)

假设在括号内只有一个逗号被替换,这个POSIX BRE sed表达式将用冒号替换它:

sed 's/(\(.*\),\(.*\))/(\1:\2)/g' file

如果有多个逗号,只会替换最后一个

在多逗号场景中,您可以将仅替换第一个

sed 's/(\([^,]*\),\([^)]*\))/(\1:\2)/g' file

答案 1 :(得分:4)

这是awk的一个版本,它使用括号作为记录分隔符:

awk -v RS='[()]' 'NR%2 == 0 {sub(/,/,":")} {printf "%s%s", $0, RT}' file

括号之间的内容将是每个偶数记录。 RT变量包含与此记录的RS模式匹配的字符。

请注意,这只会替换带括号的文本的第一个逗号。如果您要替换所有内容,请使用gsub代替sub

答案 2 :(得分:2)

虽然@randomir's sed solution专注于替换括号内的单个逗号,但有一种方法可以用sed替换括号内的多个逗号。

以下是代码:

sed '/(/ {:a s/\(([^,()]*\),/\1:/; t a}'

sed '{:a;s/\(([^,()]*\),/\1:/;ta}'

sed -E '{:a;s/(\([^,()]*),/\1:/;ta}'

查看online demo

在所有情况下,主要部分在花括号之间。以下是POSIX ERE(sed-E选项)模式的详细信息:

  • :a;
  • s/(\([^,()]*),/\1:/; - 找到并捕获到第1组
    • \( - (字符
    • [^,()]* - 除,()以外的零个或多个字符(因此,只会删除位于最近的字符之间的逗号 ()字符,不在(..,.(...,.)内 - 从括号表达式中移除(以便在后面的模式中匹配)
    • \1: - 并替换为第1组内容+后面的冒号
  • ta - 如果在前一次迭代中匹配,则循环到:a

答案 3 :(得分:1)

使用 awk

$ awk -v FS="" -v OFS="" '{ c=0; for(i=1; i<=NF; i++){ if( $i=="(" || $i ==")" ) c=1-c; if(c==1 && $i==",") $i=":" } }1' file
There is stuff here (word: word number phrases)
(word number anything: word phrases), even more

-v FS="" -v OFS=""FS设置为null,以便将每个char视为一个字段。

设置变量c=0。使用for循环对每个字段进行迭代,如果遇到c(,则切换)的值。
如果出现c==1,,则将其替换为:

答案 4 :(得分:1)

使用perl

$ perl -pe 's/\([^()]+\)/$&=~s|,|:|gr/ge' ip.txt
There is stuff here (word: word number phrases)
(word number anything: word phrases), even more

$ echo 'i,j,k (a,b,c) bar (1,2)' | perl -pe 's/\([^()]+\)/$&=~s|,|:|gr/ge'
i,j,k (a:b:c) bar (1:2)

$ # since only single character is changed, can also use tr
$ echo 'i,j,k (a,b,c) bar (1,2)' | perl -pe 's/\([^()]+\)/$&=~tr|,|:|r/ge'
i,j,k (a:b:c) bar (1:2)
  • e已修改允许在替换部分中使用Perl代码
  • \([^()]+\)将非嵌套()
  • 中的一个或多个字符匹配
  • $&=~s|,|:|gr对匹配的文字执行另一次替换,r修饰符将返回修改后的文字