파일의 열을 기준으로 중복 항목 찾기

파일의 열을 기준으로 중복 항목 찾기

세미콜론으로 구분되고 md5 해시로 정렬된 파일 경로와 해당 md5sum을 포함하는 입력 파일이 있습니다.

/media/LaCie/Images/recup2/recup_dir.1/f1295328.jpg;0080ececd3da8533f5d11e449cf73287
/media/LaCie/Documents/pics/897_FUJI/DSCF7042.JPG;0081cd15705f0c541995e13ad3e405b8
/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729.JPG;00829232ae6b181654ee87ff32d161f8
/media/LaCie/Images/Trashes/501/IMG_0651.JPG;00833c74523d5361641af863f5d92387
/media/LaCie/Images/2009-09/IMG_0651.JPG;00833c74523d5361641af863f5d92387

해시를 기반으로 중복 항목을 찾아 인쇄하는 방법을 알고 싶습니다. 따라서 위 입력에 대한 출력은 다음과 같습니다.

/media/LaCie/Images/Trashes/501/IMG_0651.JPG;00833c74523d5361641af863f5d92387
/media/LaCie/Images/2009-09/IMG_0651.JPG;00833c74523d5361641af863f5d92387

을 시도했지만 uniq필드 구분 기호를 공백에서 세미콜론으로 변경하는 방법을 찾을 수 없습니다(일부 파일 경로에는 공백이 있을 수 있음).

답변1

경로에 공백이나 세미콜론이 포함되어 있지 않으면 세미콜론을 공백으로 바꾸십시오.

tr ';' ' ' | uniq -f 1 -d | tr ' ' ';'

경로에 공백이 포함되어 있지만 탭이나 세미콜론이 없는 경우 기본적으로 동일한 작업을 수행할 수 있습니다. 단, 일시적으로 공백을 세미콜론으로 바꾸고 탭을 필드 구분 기호로 사용합니다.

tr '; ' '\t;' | uniq -f 1 -d | tr '\t;' '; '

파일 이름에 대해(개행 문자를 포함하지 않는 것 제외) 어떤 가정도 하지 않으려면 awk가 대신 작업을 수행하도록 할 수 있습니다.

awk -F ';' '{
    if ($NF == current) {
        if (first != "") print first;
        first = "";
        print;
    } else {
        first = $0;
        current = $NF;
    }
}'

답변2

가능한 해결책은 다음을 사용하는 것입니다 awk.

awk -F";" 'FNR == NR { x[$2]++; next; } { if ($2 in x && x[$2] > 1) print; }' file file

주의할 점은 파일을 두 번 읽는다는 것입니다. 첫 번째 패스에서는 반복 횟수를 계산하고 배열에 저장하며, 두 번째 패스에서는 카운터가 1보다 크면 행을 인쇄합니다.

답변3

매우 쉽습니다 perl(보너스 포인트를 얻으려면 md5sum약간의 작업도 수행할 수 있습니다).

그러나 다음과 같은 것 :

#!/usr/bin/env perl
use strict;
use warnings;

my %file_md5; 

while ( <> ){
   chomp; 
   my ( $filename, $hash ) = split /;/; 
   if ( $file_md5{$hash} ) { 
       print "$filename has the same md5sum as $file_md5{$hash}\n";
   }
   $file_md5{$hash} = $filename;
}

참고 <>는 마법의 파일 핸들입니다. STDIN명령줄의 파일을 통해 또는 파일에서 스크립트로 파이프된 데이터를 가져옵니다../myscript.pl file_containing_data

답변4

더 똑똑한 솔루션 중에는 cutmd5sum을 꺼내서 실행하여 uniq -c개수를 얻고 awk실제로 고유한 값을 제거한 다음 나머지 md5sum을 루프를 통해 일치하는 값 for으로 전달하는 무차별적인 "한 줄짜리" 방법이 있습니다. grep원본 파일에서. 확실히 Gilles의 all-awk 솔루션만큼 우아하지는 않으며 입력 파일을 두 번 읽는 단점도 있습니다.

for md5 in $(cut -d\; -f2 inputfile-here | uniq -c | awk '$1 > 1 { print $2 }')
do 
  grep ";$md5\$" inputfile-here
  echo  ## gratuitous blank line to separate the duplicates
done

샘플 입력 파일에 추가 중복 항목을 추가했습니다.

/media/LaCie/Images/recup2/recup_dir.1/f1295328.jpg;0080ececd3da8533f5d11e449cf73287
/media/LaCie/Documents/pics/897_FUJI/DSCF7042.JPG;0081cd15705f0c541995e13ad3e405b8
/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729.JPG;00829232ae6b181654ee87ff32d161f8
/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729-1.JPG;00829232ae6b181654ee87ff32d161f8
/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729-2.JPG;00829232ae6b181654ee87ff32d161f8
/media/LaCie/Images/Trashes/501/IMG_0651.JPG;00833c74523d5361641af863f5d92387
/media/LaCie/Images/2009-09/IMG_0651.JPG;00833c74523d5361641af863f5d92387

위의 루프는 다음을 생성합니다.

/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729.JPG;00829232ae6b181654ee87ff32d161f8
/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729-1.JPG;00829232ae6b181654ee87ff32d161f8
/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729-2.JPG;00829232ae6b181654ee87ff32d161f8

/media/LaCie/Images/Trashes/501/IMG_0651.JPG;00833c74523d5361641af863f5d92387
/media/LaCie/Images/2009-09/IMG_0651.JPG;00833c74523d5361641af863f5d92387

관련 정보