列ごとにディレクトリ内のすべてのcsvファイルをマージします。

列ごとにディレクトリ内のすべてのcsvファイルをマージします。

ディレクトリに3つのcsvファイルが含まれているとします。

最初のCSV:

Name, John
Age, 18

2番目のCSV:

Name, Jim
Age, 21

3番目のCSV:

Name, Amy
Age, 22

私は結果が次のようになりたいと思います:

Name, John, Jim, Amy
Age, 18, 21, 22

ディレクトリにn個のcsvがある可能性があることを知ることが重要です。 bash および posix シェルを使用できます。

編集する:

これはうまくいきますが、まだ順序に問題があります。

awk -F, -v OFS="," '{a[FNR]=a[FNR]?a[FNR]FS$2:$1FS$2}END{for(x in a)print x,a[x]}' *.csv > results.csv

FNR 1は配列の最初でなければなりませんが、最後に印刷されるため、これは意味がありません。

答え1

あなたの試みは非常に近いです。必要に応じて機能するためのいくつかの修正は次のとおりです。

awk -F, -v OFS="," '{
        a[FNR] = (FNR==NR ? $0 : a[FNR] OFS $2)
    }
    END { 
        for(i=1;i<=FNR;i++) print a[i]
    }' *.csv

for (x in a)配列アクセス順序は保証されていないため、順序を維持するためにループを介して数値インデックスを実行しますfor。を使用することもできますが、for (i=1;i<=length(a);i++)配列を引数として渡すことがlength()すべてのawksの標準ではないことを知っておくことをお勧めします。GNU awk マニュアル

また見なさい:スキャンアレイ

また、「最初のファイルを解析するとき」というイディオムである条件文を使用し、行FNR==NR全体を保存したいと思います。$0次のファイルには2番目のフィールドのみを追加します。

答え2

データが転置されたテーブル形式( "xtab")のように見えますが、キーと値のペアの区切り文字はタブではなくコンマであり、スペースが多すぎます。

データをクリーンアップしてCSVに変換するには、Miller(mlr)を使用できます。

$ mlr --ixtab --ips , --ocsv clean-whitespace fileA fileB fileC
Name,Age
John,18
Jim,21
Amy,22

--ipsキーと値の間に使用される区切り記号である「ペア区切り記号」を設定します。

datamashフィールドにカンマや改行文字が含まれていないと仮定すると、GNUを使用して置き換えることが最も簡単です。

$ mlr --ixtab --ips , --ocsv clean-whitespace fileA fileB fileC | datamash -t, transpose
Name,John,Jim,Amy
Age,18,21,22

入力フィールドにカンマが含まれている場合は、他の出力フィールド区切り記号(データには表示されない区切り文字)を指定してdatamash使用するように指示できます。

$ mlr --ixtab --ips , --ocsv --ofs pipe clean-whitespace fileA fileB fileC | datamash -t '|' transpose
Name|John, the dapper|Jim, the mighty|Amy, the awesome
Age|18|21|22

関連情報