共通列に基づいて複数のファイルをマージし、ファイルに対応する共通列がない場合はゼロを追加したいと思います。たとえば、下の図を参照してください。
a1.txt
111,222,444,5.5
121,321,555,1.2
a2.txt
111,222,444,7.8
333,321,555,4.5
311,555,222,1.1
a3.txt
333,321,555,9.1
311,555,222,8.8
444,666,777,2.5
一致は最初の3列の組み合わせでなければなりません。
出力は次のようになります。
111,222,444,5.5,7.8,0
121,321,555,1.2,0,0
333,321,555,0,4.5,9.1
311,555,222,0,1.1,8,8
444,666,777,0,0,2.5
3つの入力ファイルのうち4列目の値が異なるので、順番に配置したいと思います。 a1.txt値と同様に、出力ファイルの4列目にする必要があります。 a2.txtの値は出力ファイルの列5にあり、a3.txtの値は出力ファイルの列6になければなりません。以下で試しましたが、期待した結果が得られませんでした。
awk '{ a[$1 FS $2 FS $3 FS] = a[$1 FS $2 FS $3 FS] ( a[$1 FS $2 FS $3 FS] == "" ? "" : FS) $4 } END{ for (i in a){print i,a[i,0],a[i]} }' FS="," a1.txt a2.txt a3.txt
だから4つ、5つ、6つの入力ファイルに対して同じことをしたいと思います。誰でもこの問題を解決するのに役立ちますか?
ベストアンサー1
awkを使用し、出力でレコードの順序を維持します。
awk 'BEGIN{ SUBSEP=OFS=FS="," }
FNR==1 && !reProccss{ fileNr++ }
!reProccss{ keys[$1, $2, $3, fileNr]=$4; next }
reProccss{ key=($1 OFS $2 OFS $3); recNr++
for(i=1; i<=fileNr; i++)
if(seen[key]++<fileNr){
join[key]= join[key] OFS ((key, i) in keys ?keys[key, i]:"0")
data[recNr]= key join[key]
}
}
END{ for(rec=1; rec<=recNr; rec++)
if(data[rec]!="")
print data[rec]
}' a[1-3].txt reProccss=1 a[1-3].txt
または、join
+シェルを使用して複数の列をキーで単一のキーに変換し、次のようjoin
な答えでコマンドを使用します。最初の列に複数のファイルをマージする(結合は単一の列をキーとして使用しなければ機能しないため)、目的の出力を生成します。
-
そのため、最初の2つのファイルの特定の文字(入力ファイルに含まれてはいけない文字など)で区切って、複数のキー列を1つのキー列に変換して一時ファイルに出力します。joined.tmp
:
join -t, -a1 -a2 -e 0 -o auto \
<(<a1.txt sort |awk -F, -v OFS='-' '{ print $1, $2, $3 FS $4 }') \
<(<a2.txt sort |awk -F, -v OFS='-' '{ print $1, $2, $3 FS $4 }') > joined.tmp
次に、シェルループを使用して残りのファイルを処理します。joined.tmp
ファイル(次のファイルに関連付けるために実行されるたびに更新されます)、ループですでに処理されている最初の2つのファイルもスキップされます。
for file in ./a*.txt; do
[ "$file" = "./a1.txt" -o "$file" = "./a2.txt" ] && continue
join -t, -a1 -a2 -e 0 -o auto \
joined.tmp <(sort "$file" |awk -F, -v OFS='-' '{ print $1, $2, $3 FS $4 }') >joined.tmp.1
mv joined.tmp.1 joined.tmp
done
最後に追加された文字を-
元の文字に戻します,
。
sed 's/-/,/g' joined.tmp > joined-final.csv
join
入力ファイルをソートする必要があるため、出力のレコードの順序が変わります。
$ cat joined-final.csv
111,222,444,5.5,7.8,0
121,321,555,1.2,0,0
311,555,222,0,1.1,8.8
333,321,555,0,4.5,9.1
444,666,777,0,0,2.5