【问题标题】:Sed replace at second occurrence第二次出现 Sed 替换
【发布时间】:2017-09-15 11:47:00
【问题描述】:

我想用 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 个或更多 (null)s 并且您仍然想只删除第二次出现,我认为使用 perl 会更容易,使用 .*? 而不是 .* .

标签: regex bash sed non-greedy


【解决方案1】:

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(后来编辑为//2)......所以你只是被贪婪的问题推迟了......在这种情况下很容易解决因为有[^,] 或[^.] 的解决方法...对于一般情况,您可能需要在 perl/python/etc 中提供适当的 csv 解析器
  • 你说得对,我可以使用我在脚本中使用的 pyexcel 来完成此操作。没想到!
  • 啊,这正是我需要的,谢谢!
【解决方案2】:

更强大的 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

【讨论】:

  • 太棒了,这工作得很好!我将不得不检查更多关于 awk 工具的信息!
【解决方案3】:

执行:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多