私はスクリプトが初めてです。 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,6Apex_20_Latest.csv:
A、雨、種
4,5,6
5,6,7
6,7,8Apex_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
列数が最も多い行が最初に出るように、sort
2番目のフィールド(30、20、10..)とファイルに基づいてファイル名を逆に変更できます。cat
awk
その後、最初の行で最も多くの列を取得できますNF
NR
if (NR==1){nfm=NF}
次に、(列番号)がフィールド番号に印刷された値以上で、その後に「、」が続くfor
までループを実行します。フィールドに値がない場合にのみ印刷されます(最新のファイルよりも列数が少ない場合に発生します)。i
nfm
i
i
,
答え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はデフォルトで名前付き列を処理するため、ヘッダー行の管理が簡単になります。