나는 다음과 같이 Solaris 5.8 버전에 두 개의 간단한 파일을 포함시키려고 합니다:
~/temp/s: cat 1
work1 a 8058 51
work2 b 15336 51
~/temp/s: cat 2
8058 77-11:29:32 /apps/sas
15336 100-12:23:49 /local/hotfix
~/temp/s: join -1 3 -2 1 1 2
8058 work1 a 51 77-11:29:32 /apps/sas (The other line is missing from the output)
출력에는 두 개의 레코드가 있어야 하는데 하나의 레코드만 포함됩니다. 무엇이 잘못되었는지 잘 모르겠습니다.
출력의 모든 레코드를 얻을 수 있는 방법이 있습니까?
답변1
조인 키는 사전순으로 정렬되어야 합니다.
따라서 프로세스 대체(ksh93, zsh, bash)를 지원하는 쉘을 사용하고 다음을 수행하십시오.
join -1 3 -2 1 <(sort -k 3,3 1) <(sort -k 1,1 2)
또는 POSIX/Bourne 쉘을 사용하십시오:
sort -k 3,3 1 | {
sort -k 1,1 2 | join -1 3 -2 1 /dev/fd/3 -; } 3<&0
join
작동 방식을 이해하는 데 도움이 됩니다 . join
파일을 한 줄씩 동시에 읽고 조인 키를 비교합니다. 동일하면 일치 항목을 얻고 결과를 출력합니다. key1 < key2이면 key1이 key2와 같을 때까지(또는 그보다 클 때까지 file1을 계속 읽습니다. 이 경우 시작합니다) file2 등을 읽습니다.)
이는 파일이 키별로 정렬되지 않은 경우 작동하지 않는 이유를 설명합니다.
join
이것은 확장을 제외한 각각의 경우이며 join
GNU는 키가 일치하는 한 불평하지 않습니다. 그러나 행이 키를 기준으로 정렬되지 않은 경우 다른 경우와 마찬가지로 첫 번째 불일치에서 실패합니다.
답변2
내 생각엔 이것이 버그일지도 모른다 join
. 방금 다음 버전을 사용하여 Fedora 14에서 사용해 보았습니다 join
.
$ join --version
join (GNU coreutils) 8.5
예
$ join -1 3 -2 1 1 2
8058 work1 a 51 77-11:29:32 /apps/sas
15336 work2 b 51 100-12:23:49 /local/hotfix
선택하다
다음을 사용할 수 있습니다 awk
.
$ awk 'NR==FNR{_[$3]=$3;next}$1 in _{print _[$1],$0}' 1 2
8058 8058 77-11:29:32 /apps/sas
15336 15336 100-12:23:49 /local/hotfix