複数の区切りファイルのデータを変数列を含む1つのファイルにまとめます。

複数の区切りファイルのデータを変数列を含む1つのファイルにまとめます。

私はスクリプトが初めてです。 Unixでファイルのマージの問題が発生しました。方向を探していましたが、偶然このサイトを見つけました。すばらしい投稿と回答をたくさん見ましたが、私の問題に対する解決策が見つかりませんでした。どんな助けにも感謝します..

3つのcsvファイル(> Apex_10_Latest.csv、Apex_20_Latest.csv、Apex_30_Latest.csv)があります。この3つのファイルの列数は異なります。通常、番号によっては、最新のファイルの末尾に新しい列が追加されることがあります。だから私は最新のヘッダーを取得し、3つのファイルすべてのデータを新しいファイルApex.csvにスタックしたいと思います。最新のファイルよりも列数が少ない古いファイルのデータをスタックするときは、適切な区切り文字を使用してデータをNULLで埋めたいと思います。

また、この作業は、同じフォルダー内の複数のファイルセット(それぞれ3つのファイル)に対して繰り返し実行する必要があります。 - Apex_10_Latest.csv, Apex_20_Latest.csv, Apex_30_Latest.csv - Apex.csv로 병합 - Code_10_Latest.csv, Code_20_Latest.csv, Code_30_Latest.csv - Code.csv로 병합 - Trans_10_Latest.csv, Trans_20_Latest.cs v. Trans_30_Latest.csv - ImportTrans.csv マージ

ソースファイルの形式とターゲットファイルの形式は次のとおりです。ソースファイル:

  • Apex_30_Latest.csv:
    ABCD
    1,2,3,4
    2,3,4,5
    3,4,5,6

  • Apex_20_Latest.csv:
    A、雨、種
    4,5,6
    5,6,7
    6,7,8

  • Apex_10_Latest.csv:
    A、雨
    7,8
    8,9
    9,10

意図したターゲットファイル:

  • Apex.csv
    ABCD
    1,2,3,4
    2,3,4,5
    3,4,5,6
    4,5,6,,
    5,6,7,,
    6,7,8,,
    7,8,,,
    8, 9,,,
    9,10,,,

ありがとうございます...

答え1


ミラー(http://johnkerl.org/miller/doc/) いつものように簡単

mlr --csv unsparsify Apex_*_Latest.csv

あなたのため

A,B,C,D
1,2,3,4
2,3,4,5
3,4,5,6
4,5,6,
5,6,7,
6,7,8,
7,8,,
8,9,,
9,10,,

答え2

  cat $(ls -1 Apex_*_Latest.csv | sort -nr -k2 -t'_') | awk -F"," '{
           if (NR==1){
                nfm=NF};
           for (i=1;i<=nfm;i++) {
                printf $i","};
           print ""}' >Apex.csv

列数が最も多い行が最初に出るように、sort2番目のフィールド(30、20、10..)とファイルに基づいてファイル名を逆に変更できます。cat

awkその後、最初の行で最も多くの列を取得できますNFNR if (NR==1){nfm=NF}

次に、(列番号)がフィールド番号に印刷された値以上で、その後に「、」が続くforまでループを実行します。フィールドに値がない場合にのみ印刷されます(最新のファイルよりも列数が少ない場合に発生します)。infmii,

答え3

前回答が一番だと思います。 PerlとPythonが大きくなって以来、長年にわたってawkを使用していないので、他のアプローチを示しています。私はawkが大丈夫だと思います。ただシェル、sed、Python、および/またはPerlの混合が私の仕事に適しているということです。

しかし、この場合、誰でもawkソリューションがよりきれいで読みやすいことがわかると思います。考えてみると、awkをコマンドラインスプレッドシートにしたり、そのようなものを聞いたようです。 :-)

元の投稿に応じて、私はファイル名の形式に依存するのではなく、lsコマンドを使用してファイル名をファイルの変更時間でソートすることを選択しました。 1つは6、もう1つは6です。

したがって、比較のために効率的で移植可能でモジュラー(?!)の純粋なシェルバージョンソリューションがあります。

    #!/bin/sh

    get_commas() {
        sed 's/[^,]//g; 1q' "$@"
    }

    get_extra_commas() {
        local maxcommas="$1"
        local file="$2"
        local new_commas=$(get_commas "$file")
        local extra_commas=""
        while [ "${new_commas}${extra_commas}" != "${maxcommas}" ]
        do
            extra_commas=",$extra_commas"
        done
        echo "$extra_commas"
    }

    unset header
    ls -t Apex*.csv |
    while read filename
    do
        if [ -z "$header" ]
        then
            header="$(sed 1q "$filename")"
            commas=$(echo "$header" | get_commas)
            echo "$header"
        fi
        extra_commas=$(get_extra_commas $commas "$filename")
        sed "1d; s/\$/$extra_commas/" "$filename"
    done

答え4

これが実装された答えです。ミラー:

$ cat rect.mlr
for (k,v in $*) {
  @fields[k] = v; # retain already-seen field names
}
for (k,v in @fields) {
  if (isabsent($[k])) {
    $[k] = "";
  }
}

$ mlr --csvlite put -f rect.mlr Apex_30_Latest.csv Apex_20_Latest.csv Apex_10_Latest.csv
A,B,C,D
1,2,3,4
2,3,4,5
3,4,5,6
4,5,6,
5,6,7,
6,7,8,
7,8,,
8,9,,
9,10,,

Millerはデフォルトで名前付き列を処理するため、ヘッダー行の管理が簡単になります。

関連情報