다음과 같은 디렉터리 구조가 있다고 가정해 보겠습니다.
root
|-- dirA
|-- file.jpg
|-- file-001.jpg <-- dup
|-- file2.jpg
|-- file3.jpg
|-- dirB
|-- fileA.jpg
|-- fileA_ios.jpg <-- dup
|-- fileB.jpg
|-- fileC.jpg
|-- dirC
|-- fileX.jpg
|-- fileX_ios.jpg <-- dup
|-- fileX-001.jpg <-- dup
|-- fileY.jpg
|-- fileZ.jpg
그렇다면 루트 폴더가 있는 경우 동일한 이름(접미사만 다름)을 가진 중복 항목을 어떻게 반복적으로 찾을 수 있습니까?
이름은 임의의 문자열일 수 있지만 file...
접미사는 001, 002, 003 등이 될 수 있습니다. 그러나 3자리 패턴과 _ios
리터럴(정규식 일치를 위한)이 있을 것이라고 가정하는 것이 안전합니다.
내 리눅스 foo는별로 좋지 않습니다.
답변1
조금 길지만 명령줄입니다. 파일의 내용을 살펴보고 암호화 해시( )를 사용하여 md5sum
비교합니다 .
find . -type f -exec md5sum {} + | sort | sed 's/ */!/1' | awk -F\| 'BEGIN{first=1}{if($1==lastid){if(first){first=0;print lastid, lastfile}print$1, $2} else first=1; lastid=$1;lastfile=$2}'
아까 말했듯이 내용이 좀 길어요...
find
md5sum
현재 디렉터리 트리의 모든 파일 에 대해 실행됩니다. 그러면 출력은 sort
md5 해시를 통해 이루어집니다. 파일 이름에 공백이 있을 수 있으므로 sed
첫 번째 필드 구분 기호(공백 2개)를 수직 파이프(파일 이름에 나타날 가능성이 낮음)로 변경합니다.
마지막 awk
명령은 세 가지 변수, 즉 lastid
= 이전 항목의 md5 해시, lastfile
= 이전 항목의 파일 이름, first
= 처음으로 표시된 마지막 ID를 추적합니다.
출력에는 해시가 포함되어 있어 어떤 파일이 서로 중복되는지 확인할 수 있습니다.
이는 파일이 하드 링크(동일한 inode, 다른 이름)인지 여부를 나타내지 않으며 내용만 비교합니다.
업데이트: 파일의 기본 이름만을 기준으로 수정합니다.
find . -type f -print | sed 's!.*/\(.*\)\.[^.]*$!\1|&!' | awk -F\| '{i=indices[$1]++;found[$1,i]=$2}END{for(bname in indices){if(indices[bname]>1){for(i=0;i<indices[bname];i++){print found[bname,i]}}}}'
여기에서는 find
파일 이름을 나열하고, sed
경로 이름의 기본 이름 부분을 취하고, 기본 이름과 전체 경로 이름을 포함하는 2필드 테이블을 만듭니다. 그런 다음 awk
본 경로 이름("발견") 테이블이 생성되고 기본 이름과 항목 번호로 색인이 생성됩니다. "인덱스" 배열은 본 기본 이름 수를 추적합니다. 그런 다음 "END" 절은 발견된 중복된 기본 이름을 인쇄합니다.
답변2
.fdupes
fslint
답변3
디렉터리 구조 생성
mkdir dir{A,B,C}
touch dirA/file{,-001,2,3}.jpg
touch dirB/file{A,A_ios,B,C}.jpg
touch dirC/file{X,X_ios,X-001,Y,Z}.jpg
여러 중복 파일 표시
find . -name '*.jpg' -type f |sed 's/\(.*\/\(file.\).*\(.jpg\)\)/\2/' |sort |uniq -c|grep -v 1
상품을 반품하다
2 파일 A
3 파일 X