CSVファイルの列を別々のファイルに分割する方法は?

CSVファイルの列を別々のファイルに分割する方法は?

list.csv以下のようにcsvファイルがあります。

Pcissicola19,cissicola39,12xbauhiniae
BGDHLHFA_02833,DGDFDEGP_00879,POPGJMOL_04119
BGDHLHFA_01427,DGDFDEGP_03106,POPGJMOL_01558
BGDHLHFA_01618,DGDFDEGP_02529,POPGJMOL_04348
BGDHLHFA_01349,DGDFDEGP_02811,POPGJMOL_04175
BGDHLHFA_01734,DGDFDEGP_04039,POPGJMOL_04234
BGDHLHFA_00509,DGDFDEGP_02546,POPGJMOL_00085
BGDHLHFA_04577,DGDFDEGP_04242,POPGJMOL_00124

各列の最初のフィールドを除くすべての列を、各列の最初のフィールド名を持つ新しいファイルに個別に印刷する必要があります。予想される出力は次のとおりです。

ピッチシコーラ19.txt

BGDHLHFA_02833
BGDHLHFA_01427
BGDHLHFA_01618
BGDHLHFA_01349
BGDHLHFA_01734
BGDHLHFA_00509
BGDHLHFA_04577

ししこら39.txt

DGDFDEGP_00879
DGDFDEGP_03106
DGDFDEGP_02529
DGDFDEGP_02811
DGDFDEGP_04039
DGDFDEGP_02546
DGDFDEGP_04242

12xRedbud.txt

POPGJMOL_04119
POPGJMOL_01558
POPGJMOL_04348
POPGJMOL_04175
POPGJMOL_04234
POPGJMOL_00085
POPGJMOL_00124

次のコマンドを使用して各列を印刷できますが、最初のフィールド awk -F "," '{print $1}' list.csvに基づいてファイルを保存し、すべての新しいファイルから最初のフィールドを削除するという点で、私の目的には適合しません。このプロセスを自動化するのに役立ちます。よろしくお願いします。

答え1

awk -F, 'NR==1{ split($0, tmp, ","); next }
              { for(col=1; col<=NF; col++){ print $col >>tmp[col]; close(tmp[col])} }' infile

存在するNR==1{ split($0, tmp, ","); next };NRどこアッ総代表者数窒素数量最初の行についてこれまでに読んだ/見たレコード。NRはい1、確認中ですNR==1、それが最初の行であれば、次のブロックが実行されます。分かれる()行をコンマ区切りのフラグメントに分割し、そのフラグメントを配列,に保存しますtmp。そしてnext行を読みます。

2番目のブロックでは、ループを回します。窒素数量F現在の入力レコードのフィールドを検索し、その列を配列の$col関連ファイル名tmpに印刷(追加)します。列番号と同じです。

答え2

システムが一度にプロセスを開くことを可能にする最大値(またはそれより少ない場合はawk)を超えるのに十分な列がある場合は、GNU awkを使用して多数のオープンファイルを管理します。

$ cat tst.awk
BEGIN { FS="," }
NR==1 {
    for (i=1; i<=NF; i++) {
        out[i] = $i ".txt"
    }
    next
}
{
    for (i=1; i<=NF; i++) {
        print $i > out[i]
    }
}

$ awk -f tst.awk list.csv

$ head *.txt
==> 12xbauhiniae.txt <==
POPGJMOL_04119
POPGJMOL_01558
POPGJMOL_04348
POPGJMOL_04175
POPGJMOL_04234
POPGJMOL_00085
POPGJMOL_00124

==> Pcissicola19.txt <==
BGDHLHFA_02833
BGDHLHFA_01427
BGDHLHFA_01618
BGDHLHFA_01349
BGDHLHFA_01734
BGDHLHFA_00509
BGDHLHFA_04577

==> cissicola39.txt <==
DGDFDEGP_00879
DGDFDEGP_03106
DGDFDEGP_02529
DGDFDEGP_02811
DGDFDEGP_04039
DGDFDEGP_02546
DGDFDEGP_04242

それ以外の場合は、awkを使用して必要な数の列を処理します。

$ cat tst.awk
BEGIN { FS="," }
NR==1 {
    for (i=1; i<=NF; i++) {
        out[i] = $i ".txt"
        printf "" > out[i]
        close(out[i])
    }
    next
}
{
    for (i=1; i<=NF; i++) {
        print $i >> out[i]
        close(out[i])
    }
}

答え3

または使用bashcuttr

#!/bin/bash

id=0
while read filename; do
  id=$((id+1))
  tail -n +2 list | cut -d"," -f $id >> "$filename"
done < <(head -1 list.csv | tr "," "\n")

答え4

  • 組み合わせて使用​​できます。強く打つそしてアッ:

    for n in 1 2 3; do awk -F "," "{if (NR!=1) {print \$$n}}" list.scv > $(awk -F "," "{if (NR==1) {print \$$n}}" list.scv) ; done
    
  • 例: ここに画像の説明を入力してください。

関連情報