【问题标题】:awk split more columns and print first wordawk 拆分更多列并打印第一个单词
【发布时间】:2021-09-29 19:43:09
【问题描述】:

我有逗号分隔的文件,我想以相同的拆分条件 split($column,a,"-") 将第 15 列拆分为 $NF(第 15 列到最后一列)并打印每个拆分列 a[1]。我不能从第 n 个到最后一个列循环并为每个列打印。

awk -F',' -v OFS="\t" '{for(i;$15<i<$NF,i+1);split($i,a,"_"); print ???}' file.csv

文件打印表格第 15 列示例:

NBPF1-chr1-16579269-16579502-MedEx,NBPF1-chr1-16580779-16580863-MedEx,NBPF1-chr1-16581333-16581592-MedEx,NBPF1-chr1-16582457-16582758-MedEx,NBPF1-chr1-16583499-16583796-MedEx

我的期望:

NBPF1,NBPF1,NBPF1,NBPF1,NBPF1,NBPF1

谢谢。

【问题讨论】:

  • 我认为你很接近:{for(i=15;i&lt;=$NF;++i){split($i,a,"-"); print a[1]}}
  • $NF是最后一个字段内容,NF是数字,注意区别。

标签: loops awk sed split cut


【解决方案1】:

使用您显示的示例,请尝试遵循awk 代码。更改i=15 或任何您想要开始循环的字段,直到awk 代码后面的当前行的最后一个字段。

awk '
BEGIN{
  FS=OFS=","
}
{
  value=""
  for(i=1;i<=NF;i++){
    split($i, a, /-/)
    value=(value?value OFS:"")a[1]
  }
  print value
}
'  Input_file

【讨论】:

    【解决方案2】:
    $ awk '{gsub(/-[^,]*/,"")}1' file
    NBPF1,NBPF1,NBPF1,NBPF1,NBPF1
    
    $ sed 's/-[^,]*//g' file
    NBPF1,NBPF1,NBPF1,NBPF1,NBPF1
    

    如果这不是您真正需要的,请编辑您的问题以提供更具代表性的示例输入/输出。

    【讨论】:

      【解决方案3】:

      你可以使用这个awk:

      awk 'BEGIN {FS=OFS=","} {for(i=1; i<=NF; ++i) {
      split($i, a, /-/); printf "%s%s", a[1], (i<NF ? OFS : ORS)}}' file
      
      NBPF1,NBPF1,NBPF1,NBPF1,NBPF1
      

      将i=1 更改为i=15 或您要开始从中提取- 分隔值的任何字段位置。

      【讨论】:

        【解决方案4】:
        cut -d, -f15- file | sed 's/-[^,]*//g'
        

        【讨论】:

          【解决方案5】:

          另一个例子,纯粹使用正则表达式替换:

          awk '{gsub(/^([^,]*,){14}/,"")}gsub(/-[^,]*(,|$)/,"\t")' file.csv
          

          这个刚刚从 $0 中删除了前 14 列,然后在剩余的每一列中删除了 - 和它之后的内容。
          用 gnu awk 测试过。

          示例输入:

          1,2,3,4,5,6,7,8,9,10,11,12,13,14,NBPF1-chr1-16579269-16579502-MedEx,NBPF1-chr1-16580779-16580863-MedEx,NBPF1-chr1-16581333-16581592-MedEx,NBPF1-chr1-16582457-16582758-MedEx,NBPF1-chr1-16583499-16583796-MedEx
          1,2,3,4,5,6,7,8,9,10,11,12,13,14,NBPF1-chr1-16579269-16579502-MedEx,NBPF1-chr1-16580779-16580863-MedEx,NBPF1-chr1-16581333-16581592-MedEx,NBPF1-chr1-16582457-16582758-MedEx,NBPF1-chr1-16583499-16583796-MedEx
          1,2,3,4,5,6,7,8,9,10,11,12,13,14,NBPF0-chr1-16579269-16579502-MedEx,NBPF1-chr1-16580779-16580863-MedEx,NBPF1-chr1-16581333-16581592-MedEx,NBPF1-chr1-16582457-16582758-MedEx,NBPF9-chr1-16583499-16583796-MedEx
          

          输出:

          NBPF1   NBPF1   NBPF1   NBPF1   NBPF1
          NBPF1   NBPF1   NBPF1   NBPF1   NBPF1
          NBPF0   NBPF1   NBPF1   NBPF1   NBPF9
          

          【讨论】:

          • 输出不应该在每一行显示一个尾随制表符吗?
          • 好点,只是为了代码简洁我没有在这里处理:) @rowboat
          【解决方案6】:

          使用awk你可以得到它:

          awk -v RS='[-,]' 'NR%5==1' file       
          NBPF1                                   
          NBPF1
          NBPF1
          NBPF1
          NBPF1
          

          或者正是你所期望的:

          awk -v RS='[-,]' 'NR%5==1{printf "%s%s", sep, $0; sep=","} END{print ""}' file
          NBPF1,NBPF1,NBPF1,NBPF1,NBPF1
          
          

          【讨论】:

            【解决方案7】:

            换一个怎么样?
            如果您只想要拆分后的第一部分,则无需拆分并保存到临时变量:

            awk -F, -v OFS="\t" '{for(i=15;i<=NF;i++)printf "%s" OFS, gensub(/-.*/,"",1,$i);print ""}' file.csv
            

            如果会在最右边创建一个空列,如果你不想这样,那么使用这个:

            awk -F, -v OFS="\t" '{for(i=15;i<NF;i++)printf "%s" OFS, gensub(/-.*/,"","g",$i);print gensub(/-.*/,"","g",$NF)}' file.csv
            

            如果您希望输出以逗号分隔,请将 "\t" 替换为 ,。
            它适用于 GNU awk,需要实现 gensub。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-05-23
              • 1970-01-01
              • 1970-01-01
              • 2014-05-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-04-06
              相关资源
              最近更新 更多