找到两个字符模式,只替换一个字符

时间:2016-04-01 22:29:47

标签: sed substitution

在下面的数据中,我想用stdin替换所有未紧跟空格的逗号。因此,“美国总统,(1995)”中的逗号将保留,因为紧接着有空格。

~

这是我想要的输出:

10,GoldenEye (1995),Action|Adventure|Thriller  
11,"American President, The (1995)",Comedy|Drama|Romance

我已经尝试过下面的代码了,但这会替换掉两个字符而不是第一个字符。

10~GoldenEye (1995)~Action|Adventure|Thriller  
11~"American President, The (1995)"~Comedy|Drama|Romance

我得到的输出如下:

sed 's/,[^ ]/~/g' file.csv 

4 个答案:

答案 0 :(得分:0)

尝试sed 's/,\([^ \t]\)/~\1/g' file.csv
这为您提供了请求的输出。
请注意,这不会替换尾随的逗号,因此从技术上讲,它只是部分解决方案 我知道sed可以完全按照你的要求做,但我不知道怎么做。
如果你不需要转换尾随逗号那么无关紧要。

这样做会发现,[^ \t]这是一个逗号,后跟一个不是空格或制表符的字符。 '\(\)可用于“记住”匹配的内容,然后第一组'\(...\)匹配的值可以引用为\1。第二组可以引用为\ 2,等等。

答案 1 :(得分:0)

这可能适合你(GNU sed):

sed -r ':a;s/,(\S|$)/~\1/g;ta' file

这将替换所有,后跟非空格字符或文件结尾。

N.B。替换是在两个可能的过程中包括相邻的,

答案 2 :(得分:0)

如果您从未有过2个连续逗号,这将有效:

$ sed -r 's/,([^[:blank:]]|$)/~\1/g' file
10~GoldenEye (1995)~Action|Adventure|Thriller
11~"American President, The (1995)"~Comedy|Drama|Romance

或:

$ awk '{$0=gensub(/,(\S|$)/,"~\\1","g")}1' file
10~GoldenEye (1995)~Action|Adventure|Thriller
11~"American President, The (1995)"~Comedy|Drama|Romance

如果你有多个连续的逗号,那么我会坚持使用awk:

$ awk '{ while( $0!=($0=gensub(/,(\S|$)/,"~\\1","g")) ); }1' file
10~GoldenEye (1995)~Action|Adventure|Thriller
11~"American President, The (1995)"~Comedy|Drama|Romance

如果/当你有连续的逗号时,这两种方法会发生什么:

$ echo 'a,,b' | sed -r 's/,([^[:blank:]]|$)/~\1/g'
a~,b

$ echo 'a,,b' | awk '{$0=gensub(/,(\S|$)/,"~\\1","g")}1'
a~,b

$ echo 'a,,b' | awk '{ while( $0!=($0=gensub(/,(\S|$)/,"~\\1","g")) ); }1'
a~~b

上面使用gensub()的GNU awk所以我也使用了\S而不是[^[:blank]],因为解决方案需要GNU awk所以使用\S本身并不会牺牲可移植性。如果你使用GNU sed,它也会支持\S而不是[^[:blank:]],idk关于其他seds。与其他问题一样,它是:

awk '{ while( i=match($0,/,([^[:blank:]]|$)/) ) $0=substr($0,1,i-1)"~"substr($0,i+1) } 1'

答案 3 :(得分:0)

首先gsub替换第一行的逗号,后面的两个sub更改第二行的第一个和最后一个逗号。

awk 'NR<2{gsub(/,/,"~")}{sub(/1,/,"1~")}{sub(/,C/,"~C")}1' file
10~GoldenEye (1995)~Action|Adventure|Thriller 
11~"American President, The (1995)"~Comedy|Drama|Romance