fdupes -rdN보다 더 세련된 중복 항목을 삭제하는 방법이 있습니까?

fdupes -rdN보다 더 세련된 중복 항목을 삭제하는 방법이 있습니까?

최근에 중복된 항목을 많이 삭제해야 할 필요가 생겼습니다. 3~4개의 파일 시스템을 병합할 예정인데, 공간을 경제적으로 활용하고 싶습니다. 처음에는 fdupes작업에 가장 적합한 도구인 것처럼 보였지만 점점 한계에 부딪히고 있습니다.

명령을 고려하십시오 fdupes -rdN somedirectory/. 이는 일부 디렉토리의 하위 디렉토리에 있는 모든 파일의 해시를 만듭니다.

그리고 중복 항목이 발견되면 해당 항목을 삭제하여 모든 항목의 복사본이 하나만 남게 됩니다.

하지만 유지하고 싶은데 somedirectory/subdirectory1/somefile실제로 4개의 중복 항목이 있고 프로그램이 중복 항목 중 하나를 먼저 발견하면 어떻게 되나요? 그런 다음 somedirectory/subdirectory1/somefile내가 원하지 않는 삭제합니다 .

나는 어떤 중복 항목을 유지할지 어떻게든 지정할 수 있기를 원합니다. 그리고 지금까지 중복을 처리하는 표준 프로그램(duff, FSLint) 중 어느 것도 이러한 종류의 동작을 자동화하는 것을 허용하지 않는 것 같습니다. 저는 직접 롤링하고 싶지 않아서 이 질문을 하게 되었습니다.

나는 다음과 같은 것을 쓸 수 있기를 바랍니다.

killdupes -rdN --keep=filesin,somedirectories,separated,by,commas somedirectory/

답변1

귀하가 찾고 있는 기능은 재고가 없지만 fdupes포크했습니다.fdupes (내 포크 이름은 jdupes)특정 상황에서 이 문제를 해결할 수 있는 몇 가지 기능을 추가했습니다. 예를 들어, somedirectory/subdirectory1/somefile중복 항목을 자동 삭제할 때( dN스위치를 함께 사용) 유지하고 바로 아래에 별도의 파일이 없는 경우 somedirectory, 첫 번째 및 스위치(명령으로 파일을 정렬하는)를 jdupes사용하여 각 바로 아래 하위 디렉터리 경로를 제공할 수 있습니다. -line 매개변수 순서가 먼저임):subdirectory1-O

jdupes -rdNO somedirectory/subdirectory1 somedirectory/subdirectory2 somedirectory/subdirectory3

이렇게 하면 중복 세트에서 하나의 파일을 제외한 모든 파일이 자동으로 삭제되고 세트에 파일이 포함된 경우 somedirectory/subdirectory1첫 번째 파일이 자동으로 세트에 보존된 파일이 됩니다. 유지하려는 복사본 대신 다른 복제본이 보존될 수 있다는 사실과 같이 이 접근 방식에는 여전히 눈에 띄는 한계가 있지만 somedirectory/subdirectory1, 귀하와 같은 많은 경우에는 매개 jdupes변수 순서 옵션을 해결 방법으로 사용하는 것으로 충분합니다.

가까운 장래에 jdupes파일 포함/제외, -N작업 보존, 전역 또는 매개변수 기준으로 이러한 "필터 스택" 적용에 대한 엄청난 양의 제어를 가능하게 하는 필터링 시스템을 추가할 계획입니다. 이 기능은 꼭 필요합니다. 나는 "0이 아닌 중복 항목을 재귀적으로 자동 삭제하지만 항상 somedirectory/subdirectory1/somefile있는 그대로 유지"하기 위해 다음과 같은 것을 구상합니다.

jdupes -rdN --filter=preserve:somedirectory/subdirectory1/somefile somedirectory/

업데이트(2022-03-01):2020년에 추가된 확장 필터 옵션을 살펴보세요 -X. 정확히 원하는 것은 아니지만 nostronlystr필터를 사용하면 전체 경로 내에서 무시하거나 요구할 하위 문자열을 지정할 수 있습니다.

답변2

나는 이것을 다른 곳에서는 보지 못했습니다. 당신이 원하는 것은 이것이라고 말하십시오. /mnt/folder-tree-1 /mnt/folder-tree-2가 있습니다. 모든 중복 항목을 제거하고 싶지는 않지만 tree-2에 파일이 있고 tree-1에 동일한 경로와 이름을 가진 동일한 파일이 있는 경우 tree-2에서 해당 파일을 제거합니다.

경고: 이것은 매우 간결하며 제한된 쉘 기술로 이것을 복사하여 붙여넣으려고 한다면 조심하십시오.

fdupes -rn /mnt/folder-tree-1/ /mnt/folder-tree-2/ > dupes-all.txt

fgrep /mnt/folder-tree-1/ dupes-all.txt | while read line
do
if grep -q "`echo $line | sed -e 's|^/mnt/folder-tree-1/|/mnt/folder-tree-2/|'`" dupes-all.txt
then
    echo rm \"$(echo $line | sed -e 's|^/mnt/folder-tree-1/|/mnt/folder-tree-2//|')\"
fi
done > rm-v2-dupes.sh

아니면 한 줄에 모두:

fdupes -rn /mnt/folder-tree-1/ /mnt/folder-tree-2/ > dupes-all.txt; fgrep /mnt/folder-tree-1/ dupes-all.txt | while read line; do if grep -q "`echo $line | sed -e 's|^/mnt/folder-tree-1/|/mnt/folder-tree-2/|'`" dupes-all.txt; then echo rm \"$(echo $line | sed -e 's|^/mnt/folder-tree-1/|/mnt/folder-tree-2/|')\"; fi; done > rm-v2-dupes.sh

그런 다음 rm-v2-dupes.sh를 검사하고 실행합니다.

답변3

중복 파일을 함께 하드링크하는 것은 어떻습니까? 이렇게 하면 공간은 한 번만 사용되지만 여전히 모든 경로에 존재합니다. 여기서 문제는 하드링크된 파일을 제자리에서 수정해야 한다는 것입니다(파일을 삭제하고 새 콘텐츠로 다시 생성해야만 수정 가능). 다른 접근 방식은 파일을 함께 심볼릭 링크하는 것입니다. 하지만 "기본" 파일을 결정하는 것과 동일한 문제가 있습니다. 다음 스크립트를 사용하여 이 작업을 수행할 수 있습니다(단, 공백이 포함된 파일 이름은 처리하지 않는다는 점에 유의하세요).

fdupes --quiet --recurse --sameline somedirectory/ | while read SOURCE DESTS; do
    for DEST in $DESTS; do
        ln -f $SOURCE $DEST
    done
done

답변4

이전 답변에 트위스트를 추가하기 만하면됩니다. 다음 코드를 여러 번 사용했으며 | grep삭제하려는 폴더를 간단하게 격리하여 이전 답변을 약간 수정했습니다.

`fdupes -r -n -S /directory | grep /delete-from-directory | sed -r "s/^/rm \"/" | sed -r "s/$/\"/" >remove-duplicate-files.sh`

다시 말하지만, 주석 처리된 줄 없이 나열된 모든 파일을 삭제하는 sh 파일이 생성됩니다. 물론 파일을 편집하여 유지하려는 특정 줄/파일을 주석 처리할 수 있습니다.

큰 디렉토리에 대한 또 다른 힌트는 fdupes를 txt 파일로 실행한 다음 원하는 결과를 얻을 때까지 실험하는 것 | grep입니다 | sed.

`fdupes -r -n -S /directory > duplicate-files.txt`
`cat duplicate-files.txt | grep /delete-from-directory | sed -r "s/^/rm \"/" | sed -r "s/$/\"/" >remove-duplicate-files.sh`

관련 정보