2017-09-15 256 views
5

我想在sed中删除一个模式,仅在第二次发生时删除。这是我想要的,删除一个模式,但第二次出现。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 

这里的问题是,正则表达式是太贪婪,但我不能停下来。 我也试过这样,跳过“空”中第一次出现:

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

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

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

我读过?可以使正则表达式“懒”,但我不能让它锻炼。

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

如果你可能有3个或更多'(null)'s,并且你只想删除第二个事件,那么I t哼,使用'。*?'而不是'。*'来处理perl会更容易。 –

回答

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 
+0

伟大的这是工作得很好!我将不得不更多地了解awk工具! – BeGreen

4

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 

而且,不使用扩展正则表达式

+0

我试过了,如果你在我的文章中看得更近。问题是贪婪的正则表达式。我必须用'[^,] *'来改变'。*',就像你的例子。谢谢。 – BeGreen

+1

嗯,我没有注意到你已经尝试过'// 1'(稍后编辑为'// 2')...所以你只能被贪婪的问题推迟......在这种情况下容易解决,因为有使用'[^,]'或'[^。]解决方法'...对于通用情况,您可能需要在perl/python/etc中提供正确的csv解析器 – Sundeep

+1

您是对的,我可以用pyexcel完成此操作,我的脚本。没想过! – BeGreen

-1

时不需要转义()执行:

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