
최근에 중복된 항목을 많이 삭제해야 할 필요가 생겼습니다. 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
중복 항목을 자동 삭제할 때( d
및 N
스위치를 함께 사용) 유지하고 바로 아래에 별도의 파일이 없는 경우 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
. 정확히 원하는 것은 아니지만 nostr
및 onlystr
필터를 사용하면 전체 경로 내에서 무시하거나 요구할 하위 문자열을 지정할 수 있습니다.
답변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`