Sed第二次更换

时间:2017-09-15 11:47:00

标签: regex bash sed non-greedy

我想用sed删除一个模式,只是在第二次出现时。这就是我想要的,删除模式但第二次出现。

file.csv中的内容:

a,Name(null)abc.csv,c,d,Name(null)abc.csv,f
a,Name(null)acb.csv,c,d,Name(null)acb.csv,f
a,Name(null)cba.csv,c,d,Name(null)cba.csv,f

想要输出:

a,Name(null)abc.csv,c,d,Name,f
a,Name(null)acb.csv,c,d,Name,f
a,Name(null)cba.csv,c,d,Name,f

这是我试过的:

sed -r 's/(\(null)\).*csv//' file.csv

这里的问题是正则表达式过于贪婪,但我无法做到停止。 我也试过这个,跳过第一次出现的“null”:

sed -r '0,/null/! s/(\(null)\).*csv//' file.csv

也尝试了,但贪婪的正则表达式仍然是问题。

sed -r 's/(\(null)\).*csv//2' file.csv

我读过?可以使正则表达式“懒惰”,但我无法进行锻炼。

sed -r 's/(\(null)\).*?csv//' file.csv

3 个答案:

答案 0 :(得分:6)

sed确实提供了一种指定要替换的匹配项的简便方法。只需在分隔符后添加数字

$ sed 's/(null)[^.]*\.csv//2' ip.csv
a,Name(null)abc.csv,c,d,Name,f
a,Name(null)acb.csv,c,d,Name,f
a,Name(null)cba.csv,c,d,Name,f

$ # or [^,] if there are no , within fields
$ sed 's/(null)[^,]*//2' ip.csv
a,Name(null)abc.csv,c,d,Name,f
a,Name(null)acb.csv,c,d,Name,f
a,Name(null)cba.csv,c,d,Name,f

此外,不使用扩展正则表达式时无需转义()

答案 1 :(得分:1)

更强大的 awk 解决方案:

扩展样本文件input.csv

12,Name(null)randomstuff.csv,2,3,Name(null)randomstuff.csv, false,Name(null)randomstuff.csv
12,Name(null)AotherRandomStuff.csv,2,3,Name(null)AotherRandomStuff.csv, false,Name(null)randomstuff.csv
12,Name(null)alphaNumRandom.csv,2,3,Name(null)alphaNumRandom.csv, false,Name(null)randomstuff.csv

工作:

awk -F, '{ c=0; for(i=1;i<=NF;i++) if($i~/\(null\)/ && c++==1) sub(/\(null\).*/,"",$i) }1' OFS=',' input.csv

输出:

12,Name(null)randomstuff.csv,2,3,Name, false,Name(null)randomstuff.csv
12,Name(null)AotherRandomStuff.csv,2,3,Name, false,Name(null)randomstuff.csv
12,Name(null)alphaNumRandom.csv,2,3,Name, false,Name(null)randomstuff.csv

答案 2 :(得分:-2)

执行:

awk '{sub(/.null.....csv,f/,",f")}1' file

输出应为:

a,Name(null)abc.csv,c,d,Name,f
a,Name(null)acb.csv,c,d,Name,f
a,Name(null)cba.csv,c,d,Name,f