如果找到 4 位数字,则在 csv 中打印数字和下一行值

如果找到 4 位数字,则在 csv 中打印数字和下一行值

我有 csv 格式的数据:

125867569,98652343,7012,879456217,20121221,7065,758964231,856421345   

我想要的输出:

7012,879456217,7065,758964231  

我怎样才能做到这一点?

答案1

类似的东西可以完成这项工作:

awk -F, '{for (i=1;i<NF-1;i++) if (length($i)==4 && int($i)==$i) printf("%s,%s,", $i,$(i+1))}' input_file

如果您想要“绝对矫枉过正”的版本,它可以删除不必要的内容,并在输出中添加换行符,请尝试

awk -F, '{if (g) printf("\n"); f=0; for (i=1;i<NF-1;i++) if (length($i)==4 && int($i)==$i) {if (f) printf(","); else f=1; printf("%s,%s", $i,$(i+1)); g=1}} END{if (g) printf("\n")}' input_file

答案2

如果您的文件从不包含引号或换行符,您可以使用cut

cut -d, -f3,4,6,7 file.csv
  • -d指定分隔符
  • -f指定要输出的列

答案3

ruby -rcsv -e '
  CSV.foreach(ARGV.shift) do |row|
    puts row.each_cons(2)
            .select {|pair| pair.first =~ /^\d{4}$/}
            .flatten
            .to_csv
  end
' file.csv

答案4

您可以通过多种方式进行:

方法 1:GNU sed(启用扩展正则表达式)

解释:首先在模式空间的开头放置一个标记。查看右侧的两个字段,如果我们在右侧看到一个 4 位数字,则使标记向右跳两个字段。 OTW,使标记跳一位字段并从模式空间中删除该字段。当标记到达模式空间的末尾时,此过程停止。此时模式空间中剩下的内容就是答案。

$ sed -re '
     s/^/\n/
     :a;/\n$/!{
       s/\n([0-9]{4},[^,]+(,|$))/\1\n/;ta
       s/\n[^,]+(,|$)/\n/;ta
      }
      s/,?\n$//;/./!d
 ' file.csv

$ perl -F, -lane '$,=",";
    print  /(?:^|,)(\d{4},[^,]+)/g;
' file.csv 

$ perl -F, -lane '$,=",";
    shift(@F) =~ /^(\d{4})$/
      and push(@A, $1, shift(@F))
        while @F > 1;
    print splice @A if @A;
' file.csv

$ awk -F, -vOFS=, '{
    N = split($0, a, FS)
    $0 = ""
    for ( i=j=1; i<N; )
      if ( a[i] ~ /^[0-9]{4}$/ )
        for ( k=0; k<2; k++ )
          $(j++) = a[i++]
      else
        ++i
  }NF' file.csv

相关内容