잘못된 출력을 제공하는 Join 명령이 있습니까?

잘못된 출력을 제공하는 Join 명령이 있습니까?

나는 다음과 같이 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이것은 확장을 제외한 각각의 경우이며 joinGNU는 키가 일치하는 한 불평하지 않습니다. 그러나 행이 키를 기준으로 정렬되지 않은 경우 다른 경우와 마찬가지로 첫 번째 불일치에서 실패합니다.

답변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

관련 정보