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(拡張正規表現を有効にする)

説明:まず、パターンスペースの先頭にトークンを配置します。右側の2つのフィールドを見て、右側に4桁の数字が表示されたら、マーカーは右側に2つのフィールドをジャンプします。 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

関連情報