나는 체계적이지 않고 여러 폴더에 파일이 중복되어 있는 거대한 노래 폴더를 가지고 있습니다.
간단한 두 가지 일치 항목을 사용하여 중복 항목을 찾아 제거할 수 있는 도구나 스크립트를 추천해야 합니다.
- 파일명이 똑같네요
- 파일 크기가 완전히 동일합니다.
이 경우 song.mp3
및 에 저장되는 파일 크기는 1234바이트입니다. 도구/스크립트의 복사본은 하나만 보관해야 합니다./songs/album1
/songs/albumz
나는 열심히 노력했다치카오카Fedora에서는 파일 이름이나 파일 크기로 검색할 수 있지만 검색할 수는 없습니다.둘 다함께 결합하십시오.
답변1
rdfind
원하는 대로 할 수 있지만 파일 크기 대신 암호화 해시/체크섬(md5, sha1 또는 sha256)에 의존해야 합니다.
해시 값은 파일 크기보다 더 엄격한 기준이지만 원하는 것일 수도 있고 아닐 수도 있습니다. 예를 들어, 모든 것을 고려하십시오.메타데이터음악 파일에서: 한 파일이 작곡가로 나열 되고 다른 잠재적인 중복 파일이 작곡가 Schubert
로 나열되는 경우Bruckner
그리고파일의 다른 모든 내용은 정확히 동일합니다.파일 크기 필터일치 항목으로 분류하겠지만해시 필터습관. 이것해시 필터보다 사용됩니다파일 크기 필터, 그러나 가끔씩만 중복 항목을 필터링하는 경우에는 문제가 되지 않을 수 있습니다.
실제로 실행하기 전에 원하는 결과가 나올 것이라는 확신이 들 때까지 이 옵션을 rdfind
자세히 man rdfind
읽고 사용하십시오 .-dryrun
앞으로,이 튜토리얼rdfind
중복 파일을 찾기 위한 목록 및 기타 3가지 유틸리티.
파일 크기를 필터링할 수 있는 도구는 모르지만 처음부터 새로 만들려면 find
뭔가를 함께 사용하고 엮을 것이라고 생각합니다 awk
. 이것이 당신이 원하는 것인지 알려주세요. 별로 어렵지는 않다고 생각하지만, rdfind
그것이 당신의 요구 사항을 충족한다면 별 의미가 없습니다.
답변2
실제로 이를 위해 외부 유틸리티를 사용할 필요는 없습니다. 일련의 표준 명령을 연결하여 먼 길을 갈 수 있으며, 이를 쉘 스크립트나 함수에 저장하면 항상 기억할 수 있습니다.
중복을 감지하려면 크기와 파일 이름을 기준으로 키가 지정된 연관 배열에 모든 파일 경로를 저장할 수 있습니다. 하지만 파일 모음이 많다고 말씀하셨으므로 대신 정렬하는 것이 좋습니다. 그런 다음 두 번째로 정렬합니다.고유한두 결과를 비교하면 중복된 결과가 생성되도록 하는 옵션입니다.
첫 번째 정렬의 출력을 두 번 사용하려고 합니다. 이를 위해 임시 파일을 사용할 수 있습니다. 명명된 파이프와 fifos 등은 이 간단한 작업에 그다지 도움이 되지 않습니다. 이 명령은
mktemp
디렉터리에 있는 안전하고 고유한 파일 이름을 인쇄합니다./tmp/
와 함께명령 대체$(...)
해당 이름을 이름이 지정된 변수tmp
나 다른 이름 에 할당 할 수 있습니다. 당신이 하고 있는 일을 이해하기 위해 에코하십시오.이제 크기와 파일 이름이라는 두 가지 주요 필드를 사용하고 전체 경로도 필요합니다. 편리하게도 슬래시는
/
유효한 파일 이름 문자가 아닙니다. 이는 디렉터리 이름과 파일 이름을 구분하기 위해 예약되어 있습니다. 따라서/
이 3개 필드 사이를 구분 기호로 사용할 수 있습니다 .-printf
이 명령의 기능은 다음과 같습니다find
. 모든 파일-type f
(ile)을 찾아 크기%s
, 파일 이름%f
및 전체 경로를%p
모두/
. 전체 경로에는 더 많은 슬래시가 포함되지만 처음 2개의 슬래시 구분 기호(형식에서 명시적으로 지정한 것-printf
)만 우리의 것임을 알고 있습니다.|
명령의 출력find
(크기, 파일 이름 및 전체 경로 목록) 을sort
명령에 파이프합니다. 필드가 슬래시로 구분되어 있고-t /
키가 처음 2개 필드에 있음을 알려줍니다-k 1,2
. 정렬된 목록을 임시 파일에 즉시 저장할 수 있지만tee
더 나은 성능을 위해 파이프를 열어 둘 수 있기 때문에 명령을 사용하도록 선택했습니다.|
정렬된 목록을 로 파이프하여tee
해당 목록의 복사본을 지정된 파일 이름에 저장"$tmp"
하고 어떻게든 파이프를 다음 파이프로 에코합니다.파이프는
|
tee
정렬된 목록을 동일한 키의 두 번째 목록에 반영하지만 이제 정렬 키에 OR를sort
출력합니다 .-u
--unique
|
고유한 크기 + 파일 이름 항목 목록을diff
첫 번째 입력으로 명령 에 파이프합니다-
(표준 입력), 임시 파일을"$tmp"
두 번째 파일로 사용합니다. 일반적diff
으로 변경 내용을 식별할 수 있도록 일부 플래그가 출력에 추가됩니다. 하지만 우리에게는 그것이 필요하지 않고, 우리가 필요로 하는 출력을 엉망으로 만듭니다. 우리는 고유 목록의 모든 항목이 전체 목록에도 있다는 것을 알고 있습니다. 우리는 전체 목록에 일반적인 추가 행만 원합니다. 이것이 명령의 옵션에diff
필요한 것입니다.지금까지의 명령은 중복 파일의 짧은 목록을 출력합니다. 각 중복 세트 중 하나는 고유 목록에 여전히 나타나기 때문에 생략됩니다. 이 목록의 각 항목을 처리하고 마지막 부분(전체 경로 이름)을 처리하기 위해
|
이를 구문으로 파이프합니다while read
. 주어진 매개변수 이름 아래에 각 행을 저장합니다dupl
. bash 매개변수 확장 구문을 사용하면 크기에 파일 이름과 슬래시 구분 기호를 더한#
접두어를 생략 하고 남은 것은 파일 복사본의 전체 경로입니다. 먼저 전체 명령을 실행 하고 철저하게 확인한 후 삭제 명령으로 바꾸는 것이 좋습니다. 또는 더 나은 방법은 휴지통 유틸리티 중 하나를 사용하여 중복 항목을 자신의 디렉터리로 이동하여 디렉터리를 정리하지만 아무것도 손실되지 않는 것입니다.*/*/
/
echo
rm
Trash
tmp=$(mktemp) echo temp file is "$tmp" find -type f -printf "%s/%f/%p\n" | sort -t / -k 1,2 | tee "$tmp" | sort -t / -k 1,2 -u | diff --new-line-format="%L" --unchanged-line-format="" - "$tmp" | while read dupl;do echo "${dupl#*/*/}"; done rm "$tmp"
나중에 정리하고 임시 파일을 정리하십시오
"$tmp"
.
답변3
추가 패키지를 설치하지 않고 빠른 방법은 다음과 같습니다.
#!/bin/bash
find /path/to/compare/against -type f -printf "%s %f\n" | \
while read SIZE FILE; do
find /where/to/look/for/duplicates -iname "$FILE" -size "${SIZE}c" | \
while read DUPLICATE; do
# whatever you want to do with the duplicate file
done
done