数据如下所示:
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
...
答案 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
修饰符将返回修改后的文字