【问题标题】:How do i replace comma before a specific string with \n in csv file如何在 csv 文件中用 \n 替换特定字符串之前的逗号
【发布时间】:2019-06-01 08:21:48
【问题描述】:

我有一个csv 文件,我想在GCA_* 之后用\n 替换逗号。

输入:

ASM190063v1,Escherichia coli(E.coli),strain=D3,562,SAMN03252421,PRJNA269191,Nanjing Agricultural University,2016-12-12,n/a,major,Complete Genome,full,Newbler v. 2.7,30-80x,Illumina Miseq; Roche 454 GS Junior,GCA_001900635.1,ASM301855v1,Escherichia coli (E. coli),strain=2013C-4225,562,SAMN08579596,PRJNA218110,CDC,2018-3-26,n/a,major,Complete Genome,full,HGAP v. 3,yes,76.725x,PacBio,ASM330895v1,Escherichia coli (E. coli),strain=2017C-4109,562,SAMN09534373,PRJNA218110,CDC,2018-7-10,n/a,major,Complete Genome,full,HGAP v. 3,yes,286.7X,PacBio 

期望的输出:

ASM190063v1,Escherichia coli(E.coli),strain=D3,562,SAMN03252421,PRJNA269191,Nanjing Agricultural University,2016-12-12,n/a,major,Complete Genome,full,Newbler v. 2.7,30-80x,Illumina Miseq; Roche 454 GS Junior,GCA_001900635.1
ASM301855v1,Escherichia coli (E. coli),strain=2013C-4225,562,SAMN08579596,PRJNA218110,CDC,2018-3-26,n/a,major,Complete Genome,full,HGAP v. 3,yes,76.725x,PacBio
ASM330895v1,Escherichia coli (E. coli),strain=2017C-4109,562,SAMN09534373,PRJNA218110,CDC,2018-7-10,n/a,major,Complete Genome,full,HGAP v. 3,yes,286.7X,PacBio 

我的尝试:

sed 's/ASM*/\n&/' ordered_lines_per_genome.csv > assembly_report_table.csv

【问题讨论】:

  • 你试过什么?您已使用 awk 和 sed 标记了您的问题,因此我希望在其中看到一些您需要帮助的 awk 和 sed 代码。
  • 我尝试使用 sed 命令,但对我不起作用 sed 's/ASM*/\n&/' ordered_lines_per_genome.csv > assembly_report_table.csv
  • 请将您的尝试添加到您的问题中。 (这可能会停止并且可能会扭转反对意见。)我们很乐意帮助您修复您的代码,但您的代码应该是问题的一部分。此外,您的问题表明您想在 GCA_ 之后添加换行符,但在您的示例输出中,第二个换行符不在此文本之后。你能澄清一下吗?
  • 磁贴说你想在一个字符串之前替换(我认为ASM),你想要的输出和你的尝试证实了什么。问题的第一行应该改一下,你提到GCA_这里不相关。

标签: bash awk sed


【解决方案1】:

这个简单的GNU sed 可能就是您想要的:

$ sed 's/,/\n/16;P;D' file
ASM190063v1,Escherichia coli(E.coli),strain=D3,562,SAMN03252421,PRJNA269191,Nanjing Agricultural University,2016-12-12,n/a,major,Complete Genome,full,Newbler v. 2.7,30-80x,Illumina Miseq; Roche 454 GS Junior,GCA_001900635.1
ASM301855v1,Escherichia coli (E. coli),strain=2013C-4225,562,SAMN08579596,PRJNA218110,CDC,2018-3-26,n/a,major,Complete Genome,full,HGAP v. 3,yes,76.725x,PacBio
ASM330895v1,Escherichia coli (E.coli),strain=2017C-4109,562,SAMN09534373,PRJNA218110,CDC,2018-7-10,n/a,major,Complete Genome,full,HGAP v. 3,yes,286.7X,PacBio
  • s/,/\n/16:将第 16 个逗号 , 替换为换行符 \n
  • P:将行打印到第一个换行符\n
  • D:删除打印出来的文字,用剩下的文字重新开始循环

它基于 @potong 的出色 answer

【讨论】:

  • sed 命令的确切含义进行一行解释会很棒。
  • 它当然来自一个很好的答案,但它是对另一个问题的答案。 OP 没有指定 GCA_ 将始终出现在第 16 次。 ?
  • @Tomalak 添加了解释 :) @TrebuchetMS 看起来 OP 有很长的一行,只需要格式化为正确的 csv。我认为每个csv 行具有相同数量的字段是一个公平的假设,因此我可以使用一个常量,例如16
  • 我支持这个假设。此外,OP 的示例输入已经矛盾:第二条记录中没有CGA_
  • 另一种方法16th逗号方法:xargs -d, -L 16 echo < file
【解决方案2】:

使用 GNU sed:

sed 's/\(GCA_[^,]*\),/\1\n/g' input.csv
  • \(GCA_[^,]*\),:匹配GCA*,后跟逗号。 \(...\) 定义了一个我们以后可以在替换字符串中使用的组。
  • 替换\1\n:从匹配中插入组(“GCA*”)并附加一个换行符。

直接修改文件:

sed -i 's/\(GCA_[^,]*\),/\1\n/g' input.csv

或者从评论中修复你的命令行:

sed 's/ASM[^,]*/\n&/g' input.csv

或者更好:为了防止尾随逗号:

sed 's/,\(ASM[^,]*\)/\n\1/g' input.csv

【讨论】:

  • 在 BSD 或 macOS 中不起作用。如果您不知道 OP 是否使用与您相同的版本,最好构建您的答案以便它是可移植的。
  • @ghoti 仅限于“GNU sed”
  • @ghoti 你能提供一个便携的答案吗?我想了解更多。
  • 问题是非 GNU sed 不能解释像 \n 这样的 ANSI 反斜杠符号。将换行符嵌入替换字符串的规范方法是使用文字换行符前面加上反斜杠。您可以使用格式引用在 bash 中执行此操作,如下所示:sed $'s/,ASM/\\\nASM/g' input.csv。您可以在 bash 手册页的“QUOTING”下阅读$'..'
  • 虽然在这种情况下,我认为 OP 确实希望每 16 个字段拆分一次,正如 mickp 所建议的那样,所以:sed $'s/,/\\\n/16;P;D' input.csv 可能是我的解决方案。
【解决方案3】:

您应该删除* 并为全局添加g

sed 's/ASM/\n&/g' ordered_lines_per_genome.csv > assembly_report_table.csv

不想要逗号的时候可以使用

sed 's/,ASM/\nASM/g' ordered_lines_per_genome.csv > assembly_report_table.csv

为了好玩,用 awk:

awk 'BEGIN {RS="ASM"} NF {print "ASM" $0}' ordered_lines_per_genome.csv

当你不想在行尾出现逗号时,你可以使用

awk 'BEGIN {RS="[,]*ASM"} NF {print "ASM" $0}' ordered_lines_per_genome.csv

【讨论】:

    【解决方案4】:

    awk 解决方案:

    $ awk -F, '{i=0;while((++i)<=NF)printf $i ((!(i%16) || i==NF)? ORS : ",")}' mb.csv
    ASM190063v1,Escherichia coli(E.coli),strain=D3,562,SAMN03252421,PRJNA269191,Nanjing Agricultural University,2016-12-12,n/a,major,Complete Genome,full,Newbler v. 2.7,30-80x,Illumina Miseq; Roche 454 GS Junior,GCA_001900635.1
    ASM301855v1,Escherichia coli (E. coli),strain=2013C-4225,562,SAMN08579596,PRJNA218110,CDC,2018-3-26,n/a,major,Complete Genome,full,HGAP v. 3,yes,76.725x,PacBio
    ASM330895v1,Escherichia coli (E. coli),strain=2017C-4109,562,SAMN09534373,PRJNA218110,CDC,2018-7-10,n/a,major,Complete Genome,full,HGAP v. 3,yes,286.7X,PacBio 
    

    类似于mickp's answer,16个字段为一行。
    如果您确定输入文件只有一行,则可以删除第一个i=0;

    如果'ASM'比较独特,可以使用自己的方式(ASM作为行首):

    awk '{print gensub(",ASM","\nASM","g")}' mb.csv
    

    即:

    awk '{print gensub(",ASM","\nASM","g")}' ordered_lines_per_genome.csv > assembly_report_table.csv
    

    为你。

    【讨论】:

      【解决方案5】:

      使用 Perl 并假设 id 以 ASM 开头..

      $ cat maryem.txt
      ASM190063v1,Escherichia coli(E.coli),strain=D3,562,SAMN03252421,PRJNA269191,Nanjing Agricultural University,2016-12-12,n/a,major,Complete Genome,full,Newbler v. 2.7,30-80x,Illumina Miseq; Roche 454 GS Junior,GCA_001900635.1,ASM301855v1,Escherichia coli (E. coli),strain=2013C-4225,562,SAMN08579596,PRJNA218110,CDC,2018-3-26,n/a,major,Complete Genome,full,HGAP v. 3,yes,76.725x,PacBio,ASM330895v1,Escherichia coli (E. coli),strain=2017C-4109,562,SAMN09534373,PRJNA218110,CDC,2018-7-10,n/a,major,Complete Genome,full,HGAP v. 3,yes,286.7X,PacBio
      $ perl -pe ' s/([^^]ASM.+?,)/\n$1/g; s/^,//mg; ' maryem.txt
      ASM190063v1,Escherichia coli(E.coli),strain=D3,562,SAMN03252421,PRJNA269191,Nanjing Agricultural University,2016-12-12,n/a,major,Complete Genome,full,Newbler v. 2.7,30-80x,Illumina Miseq; Roche 454 GS Junior,GCA_001900635.1
      ASM301855v1,Escherichia coli (E. coli),strain=2013C-4225,562,SAMN08579596,PRJNA218110,CDC,2018-3-26,n/a,major,Complete Genome,full,HGAP v. 3,yes,76.725x,PacBio
      ASM330895v1,Escherichia coli (E. coli),strain=2017C-4109,562,SAMN09534373,PRJNA218110,CDC,2018-7-10,n/a,major,Complete Genome,full,HGAP v. 3,yes,286.7X,PacBio
      $
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-11
        • 1970-01-01
        • 1970-01-01
        • 2017-12-02
        • 2018-08-06
        • 2012-09-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多