【问题标题】:Replacing a line in a csv file?替换csv文件中的一行?
【发布时间】:2009-01-19 22:18:28
【问题描述】:

我有一组 10 个 CSV 文件,通常有一个此类条目

a,b,c,d
d,e,f,g

现在由于这个文件中的一些错误条目变成了这种类型

a,b,c,d
d,e,f,g
,,,
h,i,j,k

现在我想删除所有文件中只有逗号的行。这些文件位于 Linux 文件系统上。

您推荐的任何可以替换所有文件中错误行的命令。

【问题讨论】:

    标签: linux command-line


    【解决方案1】:

    这取决于您所说的替换。如果您的意思是“删除”,那么@wnoise 解决方案的一个简单变体是:

    grep -v '^,,,$' old-file.csv > new-file.csv
    

    请注意,这只会删除恰好包含三个逗号的行。如果您想删除包含任意数量的逗号(包括零)且没有其他字符的格式错误的行,则:

    grep -v '^,*$' ...
    

    正则表达式还有无穷无尽的其他变体可以处理其他场景。使用引号内的逗号处理完整的 CSV 数据开始需要除正则表达式机器之外的其他东西。它可以在广泛的范围内完成,尤其是在 PCRE 或 Perl 等更复杂的正则表达式系统中。但这需要更多的工作。

    查看Mastering Regular Expressions

    【讨论】:

      【解决方案2】:
      sed 's/,,,/replacement/' < old-file.csv > new-file.csv
      

      可选地后跟 mv new-file.csv old-file.csv

      【讨论】:

      • 天哪!踢它老skool!这让我感觉很糟糕。 :-)
      • 不会删除该行...请参阅 David 以更好地使用 sed
      • 当我回答时它要求更换,而不是删除。
      • @Peter,它不是老派,它是经典的@orip,它是 sed 的一个很好的使用
      • 在 wnoise 的辩护中,它确实说首先替换;查看编辑历史。而且这种 sed 用法可以跨平台移植;使用 '-i' 的符号是 GNU sed 特有的(因此对于关于 Linux 上的文件的问题有效)。
      【解决方案3】:

      替换或删除,您的帖子不清楚...有关替换,请参阅 wnoise 的答案。对于删除,您可以使用

      awk '$0 !~ /,,,/ {print}' <old-file.csv > new-file.csv
      

      【讨论】:

        【解决方案4】:

        尝试只保留与所需格式匹配的行而不是处理一个异常呢?

        如果提供的输入是您真正想要匹配的:

        grep -E '[a-z],[a-z],[a-z],[a-z]' < oldfile.csv > newfile.csv
        

        如果输入不同,提供,正则表达式应该不会太难写。

        【讨论】:

          【解决方案5】:

          您想用某些东西替换它们,还是完全删除它们?无论哪种方式,都可以使用sed 完成。删除:

          sed -i -e '/^,\+$/ D' yourfile1.csv yourfile2.csv ...
          

          要替换:好吧,请参阅 wnoise 的答案,或者如果您不想使用输出创建新文件,

          sed -i -e '/^,\+$/ s//replacement/' yourfile1.csv yourfile2.csv ...
          

          sed -i -e '/^,\+$/ c\
          replacement' yourfile1.csv yourfile2.csv ...
          

          (应按原样输入,包括换行符)。当然,您也可以使用awkperl 执行此操作,或者,如果您只是删除行,甚至可以使用grep

          egrep -v '^,+$' < oldfile.csv > newfile.csv
          

          我测试了这些以确保它们有效,但我建议您在使用它们之前也这样做(以防万一)。您可以从sed 中省略-i 选项,在这种情况下它将打印出结果(而不是将它们写回文件),或者从grep 中省略输出重定向&gt;newfile.csv

          编辑:评论中指出,这些sed 命令的某些功能仅适用于GNU sed。据我所知,这些是 -i 选项(可以替换为 shell 重定向 sed ... &lt;infile &gt;outfile )和 \+ 修饰符(可以替换为 \{1,\} )。

          【讨论】:

          • 您的某些“sed”选项不可移植(特定于 GNU sed)。只要您意识到这一点,就不是什么大问题。
          • @Johnathan:是的,我只使用过 GNU sed,而且我往往会忘记它的扩展,除非我真的在盯着信息页面。谢谢。
          • @Dahvid :D 问题确实说“Linux 文件系统” - 鉴于该限制,您的答案是有效的。
          【解决方案6】:

          最简单的:

          $   grep -v ,,,, oldfile > newfile   
          $   mv newfile oldfile
          

          【讨论】:

          • 模式中只有 3 个逗号要被删除。 :D
          【解决方案7】:

          是的,如果您在 linux 平台上工作,awk 或 grep 是非常好的选择。但是,您可以将 perl 正则表达式用于其他平台。使用连接和拆分选项。

          【讨论】:

          • 为什么要拆分加入?是的,你当然可以使用 perl。但基本循环将使用正则表达式来匹配或不匹配要打印的行 - 我没有看到连接/拆分操作。即使是替换而不是删除也可能不会使用联接或拆分。
          猜你喜欢
          • 2021-11-20
          • 1970-01-01
          • 2019-07-10
          • 1970-01-01
          • 2015-08-18
          • 1970-01-01
          • 1970-01-01
          • 2021-08-26
          • 2011-02-26
          相关资源
          最近更新 更多