![동일한 필드의 정렬 값을 기준으로 두 개의 정렬된 파일을 병합합니다.](https://linux55.com/image/99903/%EB%8F%99%EC%9D%BC%ED%95%9C%20%ED%95%84%EB%93%9C%EC%9D%98%20%EC%A0%95%EB%A0%AC%20%EA%B0%92%EC%9D%84%20%EA%B8%B0%EC%A4%80%EC%9C%BC%EB%A1%9C%20%EB%91%90%20%EA%B0%9C%EC%9D%98%20%EC%A0%95%EB%A0%AC%EB%90%9C%20%ED%8C%8C%EC%9D%BC%EC%9D%84%20%EB%B3%91%ED%95%A9%ED%95%A9%EB%8B%88%EB%8B%A4..png)
길이가 반드시 같을 필요는 없지만 동일한 데이터 필드와 동일한 헤더를 사용하여 특정 열의 순서에 따라 유지되는 헤더 다음에 시작하여 두 개의 정렬된 파일의 행을 병합하고 싶습니다. 예를 들어 파일 1은 다음과 같습니다.
header 1
header 2
header 3
cat 4 aa
dog 5 ab
ostrich 10 cd
fish 13 cc
파일 2는 다음과 같습니다.
header 1
header 2
header 3
lemur 3 dd
alligator 4 ca
lemming 16 ad
1) 동일한 헤더를 유지하고 싶지만 2) 열 2를 기준으로 다음 행을 정렬하고 싶습니다. 내가 원하는 출력은 다음과 같습니다.
header 1
header 2
header 3
lemur 3 dd
cat 4 aa
alligator 4 ca
dog 5 ab
ostrich 10 cd
fish 13 cc
lemming 16 ad
찾아봤지만 awk
또는 을 사용하여 이 상황에 대한 해결책을 찾을 수 없습니다 join
.
답변1
awk
그리고 join
잘못된 도구입니다.
sed '/^$/q' file1; sort -snmk2,2 <(sed '1,/^$/d' file1) <(sed '1,/^$/d' file2)
답변2
최신 (버전> 4.0) GNU awk를 사용하면 할 수 있습니다
awk '
FNR>4 {a[$0]=$2; next};
NR==FNR;
END {
PROCINFO["sorted_in"] = "@val_num_asc";
for (i in a) print i;
}
' file1 file2
설명하다:
FNR>4 {a[$0]=$2; next};
머리글이 아닌 행에 대한 정렬 필드 배열 만들기NR==FNR;
첫 번째 파일에 대해서만 TRUE를 평가하고,reach에 대해서만 평가하여FNR>4
첫 번째 파일에 대해 헤더 줄이 인쇄되도록 합니다.PROCINFO["sorted_in"] = "@val_num_asc"
값을 기준으로 배열을 정렬합니다(예: 저장 필드 $2).for (i in a) print i
인쇄색인정렬된 배열(헤더가 아닌 행이 저장됨)
시험
$ awk 'FNR>4 {a[$0]=$2; next}; NR==FNR; END {PROCINFO["sorted_in"] = "@val_num_asc"; for (i in a) print i;}' file1 file2
header 1
header 2
header 3
lemur 3 dd
cat 4 aa
alligator 4 ca
dog 5 ab
ostrich 10 cd
fish 13 cc
lemming 16 ad
답변3
프로세스 대체와 함께 쉘( ksh93
, , ...)을 사용하십시오 bash
(프로세스 대체가 없는 대안은 끝 참조).
cat <( head -n 3 file1 ) \
<( sort -k2,2n <( tail -n +4 file1 | tr -s ' ' '\t' ) \
<( tail -n +4 file2 | tr -s ' ' '\t' ) | uniq )
결과는 다음과 같습니다.
header 1
header 2
header 3
lemur 3 dd
alligator 4 ca
cat 4 aa
dog 5 ab
ostrich 10 cd
fish 13 cc
lemming 16 ad
이 명령은 헤더 행을 file1
정렬 작업의 결과와 연결합니다. 정렬은 일부 입력의 두 번째 필드에서 숫자로 수행되며 중복된 행(악어, 여우원숭이, 레밍)은 uniq
결과에서 제거됩니다.
file1
정렬할 입력은 연속된 공백을 단일 탭으로 바꾸기 위해 file2
전달된 및 의 제목 없는 내용입니다 tr
(예제 데이터에는 열 사이의 공백 수가 고르지 않습니다).
결과는 탭으로 구분됩니다.
동일한 도구를 사용하는 동등한 방법:
cat <( head -n 3 file1 ) \
<( sort -k2,2n <( cat <( tail -n +4 file1 ) \
<( tail -n +4 file2 ) | tr -s ' ' '\t' ) | uniq )
cat
s 및 프로세스 대체 없이 :
{ head -n 3 file1;
{ tail -n +4 file1; tail -n +4 file2; } | tr -s ' ' '\t' | sort -k2,2n | uniq; }