여러 개의 .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
(조인된 필드 + 첫 번째 조인의 두 번째 열 및 세 번째 열 + 첫 번째 조인의 두 번째 열 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
중복 필드는 삭제됩니다.