複数の.txtファイルがあり、最初の列(番号)に基づいてファイルをマージし、欠落しているデータがある場合は「NULL」を埋めたいと思います。
ファイル1:
1 a
2 b
3 c
ファイル_2:
3 c
4 d
5 e
ファイル_3:
4 d
5 e
6 f
予想出力:
1 a NULL NULL
2 b NULL NULL
3 c c NULL
4 NULL d d
5 NULL e e
6 NULL NULL f
join -t $'\t' -a 1 -a 2 -1 1 -2 1 -e NULL -o 0,1.2,2.2 file_1 file_2 | join -t $'\t' -a 1 -a 2 -1 1 -2 1 -e NULL - file_3 > expected_output
このコマンドは、列 1、2、3 に対して正しい出力を提供します。ただし、列4には「NULL」はありません。これを解決する方法はありますか?非常に長いパイプコマンドを書くよりも複数のファイルをマージするより良い方法はありますか?
答え1
学んだ内容を広げてください。https://stackoverflow.com/a/13963634そしてプラサン
これはファイル数に関係なく機能します。
#!/bin/bash
tempdir=$(mktemp --directory)
trap "rm -r $tempdir" EXIT SIGTERM
for infile in "$@"; do
sort "$infile" > "${tempdir}/${infile}.sorted"
if [ -e "${tempdir}/final.results" ]
then
join -a1 -a2 -e "NULL" -o auto \
"${tempdir}/final.results" "${tempdir}/${infile}.sorted" \
> "${tempdir}/res"
mv "${tempdir}/res" "${tempdir}/final.results"
else
cp "${tempdir}/${infile}.sorted" "${tempdir}/final.results"
fi
done
cat "${tempdir}/final.results"
結果:
$ . join_multiple_files.sh file* | column -t
1 a NULL NULL
2 b NULL NULL
3 c c NULL
4 NULL d d
5 NULL e e
6 NULL NULL f
答え2
ほぼすべて来ました。コマンドを使用すると、次のようになります。
$ join -t $'\t' -a 1 -a 2 -1 1 -2 1 -e NULL -o 0,1.2,2.2 file_1 file_2 | join -t $'\t' -a 1 -a 2 -1 1 -2 1 -e NULL - file_3
1 a NULL
2 b NULL
3 c c
4 NULL d d
5 NULL e e
6 f
join
パイプラインで右側の書式を指定していないため、行内の列数は同じではありません。
-o 0,1.2,1.3,2.2
(結合フィールド+最初の結合の2番目の列と3番目の列+最初の結合の2番目の列file_3
)として追加すると、次のようになります。
$ join -t $'\t' -a 1 -a 2 -1 1 -2 1 -e NULL -o 0,1.2,2.2 file_1 file_2 | join -t $'\t' -a 1 -a 2 -1 1 -2 1 -e NULL -o 0,1.2,1.3,2.2 - file_3
1 a NULL NULL
2 b NULL NULL
3 c c NULL
4 NULL d d
5 NULL e e
6 NULL NULL f
最後に、GNU実装を想定できる場合は、join
正しい形式を推論することを実行し、代わりに-o auto
sumを使用できます。ただし、各ファイルのすべての行のフィールド数は、最初のファイルと最大でなければなりません。-o 0,1.2,2.2
-o 0,1.2,1.3,2.2
引用する info join
:
-o auto
キーワードを指定すると、auto
出力形式は各ファイルの最初の行から推測されます。これは、デフォルトの出力形式と同じですが、行ごとに同じ数のフィールドが出力されることを保証します。不足しているフィールドはオプションに置き換えられ、-e
重複フィールドは削除されます。