세미콜론으로 구분되고 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
더 똑똑한 솔루션 중에는 cut
md5sum을 꺼내서 실행하여 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