다른 파일의 첫 번째 열 비교 [닫기]

다른 파일의 첫 번째 열 비교 [닫기]

동일한 디렉토리에 있는 다른 파일과 파일을 비교하고 싶습니다.

file1.txt포함하다:

move 34#123#    
get 11#278    
put 33#29#567#23

file1.txt파일 1.txt2.txt.

1.txt포함하다:

move 11    
put 34    
run 13

2.txt포함하다:

get 14    
move 66

나에게 필요한 결과는 다음과 같습니다.

move 2    
get 1    
put 1

어떻게 해야 하나요?

답변1

해결책 은 다음과 같습니다 awk.

$ awk 'FNR==NR{a[$1];next}($1 in a){++a[$1]}
    END{for(i in a){print i" "a[i]}}' file1.txt 1.txt 2.txt
put 1
get 1
move 2

설명하다

  • FNR==NR{a[$1];next}file1.txt: 처리하는 동안 연관 배열에 발생 항목을 표시합니다 .$1a
  • ($1 in a){++a[$1]}: sum을 처리할 때 1.txt연관 배열에 존재하는지 2.txt확인하고 , 존재한다면 개수에 1을 더한다.$1a
  • 마지막으로 연관 배열을 반복하여 a키(파일의 첫 번째 필드)와 해당 값( 1.txt합계에서 발생 횟수 2.txt)을 인쇄합니다.

perl동일한 논리를 사용하는 의 또 다른 솔루션은 다음과 같습니다 .

$ perl -alne '++$i;                  
    if ($. == $i) {
        $h{$F[0]}=0;
        close ARGV if eof;
        next;
    }
    ++$h{$F[0]} if defined $h{$F[0]};
END {
    for (keys %h) {
        print $_." ".$h{$_};
    }
}' file1.txt 1.txt 2.txt
move 2
get 1
put 1

답변2

grep, awk, sort, & 등 다양한 도구를 사용하여 대안을 표시합니다 uniq. 물론 더 많은 도구를 사용하지만 AWK보다 무슨 일이 일어나고 있는지 이해하는 것이 더 쉽다는 것을 알았습니다.

$ for i in 1.txt 2.txt; do grep -f <(awk '{print $1}' $i) file1.txt; done | \
    awk '{print $1}' | sort | uniq -c

$ for i in 1.txt 2.txt; do grep -f <(awk '{print $1}' $i) file1.txt; done | \
    awk '{print $1}' | sort | uniq -c
      1 get
      2 move
      1 put

어떻게 작동하나요?

다음은 약간 확장된 예입니다.

$ for i in 1.txt 2.txt; do 
    grep -f <(awk '{print $1}' $i) file1.txt
  done | \
    awk '{print $1}' | sort | uniq -c

for루프는 일치시키려는 2개의 파일을 반복합니다 1.txt. 반복할 때마다 대상 파일에서 2.txt파일 중 하나의 첫 번째 열을 정적 문자열 세트로 사용합니다 .grepfile1.txt

$ grep -f <(awk '{print $1}' $i) file1.txt

루프의 각 파일에 대해 명령을 실행한 후 for모든 출력을 가져오고 그 안에 있는 첫 번째 열만 선택합니다.

move
put
move
get

그런 다음 sortsum을 사용하여 우리 uniq가 보는 각 유형의 수를 계산합니다.

답변3

또 다른 접근 방식은 다음과 같습니다 join.

join -1 1 -2 2 -o 0 2.1 <(sort -k1,1 file1.txt) <(cut -d ' ' -f1 1.txt 2.txt | sort | uniq -c)

출력은 다음과 같이 정렬됩니다.

get 1
move 2
put 1

file1.txt예를 들어 주문을 유지하려는 경우

move 2
get 1
put 1

다음을 실행할 수 있습니다.

join -j2 -o 1.1 0 2.1 <(nl -ba -nrz file1.txt | sort -k2,2) \
<(cut -d ' ' -f1 1.txt 2.txt | sort | uniq -c) | sort -k1 | cut -d ' ' -f2-

관련 정보