최근에 많은 중복을 삭제해야합니다. 3 개 또는 4 개의 파일 시스템을 병합하고 있으며 공간을 경제적으로 사용하고 싶습니다. 처음에는 fdupes이 작업에 가장 적합한 도구 인 것처럼 보였지만 점점 제한에 직면하고 있습니다.

. 이것은 somedirectory의 하위 디렉토리에있는 모든 파일의 해시를 만듭니다.

중복을 발견하면이를 삭제하여 모든 사본이 하나만 있도록합니다.

하지만 somedirectory/subdirectory1/somefile 실제로 4 개의 중복 항목이 있으며 프로그램은 먼저 중복 항목 중 하나를 발견합니까? 그런 다음 내가 원하지 않는 somedirectory/subdirectory1/somefile를 삭제합니다.

어떻게 든 유지할 중복 항목을 지정할 수 있기를 원합니다. 그리고 지금까지는 없음 중복을 처리하기위한 표준 프로그램 (duff, FSLint)은 이러한 종류의 동작을 자동화 할 수있는 것 같습니다. 저는 제 자신을 굴리는 것을 선호하지 않기 때문에이 질문을하는 것입니다.

다음과 같은 내용을 작성하고 싶습니다.

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

댓글

답변을 찾았습니다.

원하는 기능은 재고가 없지만 fdupesfdupes (내 포크는 jdupes라고 함) 이며 특정 상황에서이 문제를 해결할 수있는 몇 가지 기능을 추가했습니다. 예를 들어, 중복 항목을 자동 삭제 (dN가 함께 전환됨)하고 somedirectory, jdupessubdirectory1를 먼저 사용하고

스위치 (명령 줄 매개 변수 순서로 파일 정렬) :

jdupes -nrdNO somedirectory/subdirectory1 somedirectory/subdirectory2 somedirectory/subdirectory3

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

조만간 파일의 포함 / 제외, -N 작업에 대한 보존, 전역 또는 단위에서 이러한 “필터 스택”적용에 대한 엄청난 제어를 가능하게합니다. -매개 변수 기준. 이 기능은 절실히 필요합니다. “0이 아닌 중복 항목을 재귀 적으로 자동 삭제하지만 항상 somedirectory/subdirectory1/somefile 그대로 유지”하기 위해 다음과 같이 상상합니다.

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

답변

다른 곳에서는이 항목을 보지 못했습니다. 원하는 것을 말하세요. / 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를 검사하고 실행합니다.

답변

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

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

댓글

답변

같은 질문이있었습니다.중복 항목이 많은 경우 fdupes /my/directory/ -rdN는 수정 날짜가 가장 오래된 파일을 유지하거나 여러 파일의 수정 날짜가 동일한 경우 파일이 먼저 발견됩니다.

수정 날짜가 중요하지 않은 경우 보관하려는 디렉토리의 파일을 touch 할 수 있습니다. 현재 날짜와 시간을 touch로 선택하면 fdupes -rdNi가 현재 날짜와 함께 유지됩니다. 또는 touch 삭제하려는 파일보다 이전 날짜의 파일을 보관하고 fdupes -rdN를 정상적으로 사용할 수 있습니다.

수정 날짜를 유지해야하는 경우 다른 방법 중 하나를 사용해야합니다.

답변

이전 답변에 트위스트를 추가하십시오. 다음 코드를 여러 번 사용하여 간단한 | 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` 

답변

sed 를 사용하여 주석 처리 된 명령을 포함하는 쉘 파일을 만듭니다. 중복 파일 :

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

결과 remove-duplicate-files.sh 파일 방금 만든 e는 각 줄에 주석 처리됩니다. 삭제할 파일의 주석 처리를 제거하십시오. 그런 다음 sh remove-duplicate-files.sh 를 실행합니다. 짜잔!

업데이트

특정 디렉토리에서만 파일을 삭제하지 않으려면 다음과 같이 간단합니다. :

fdupes -S /directory|sed "/^$/d" |sed -r "s/^[0-9]/#&/" > duple_list python exclude_duplicates.py -f /path/to/dupe_list --delimiter="#" --keep=/full/path/to/protected/directory1,/full/path/to/protected/directory2\ with\ spaces\ in\ path >remove-duplicate-files-keep-protected.sh 

exclude_duplicates.py 위치 :

 #/usr/bin/python # -*- coding: utf-8 -*- # exclude_duplicates.py """ THE SCRIPT DOESN"T DELETE ANYTHING, IT ONLY GENERATES TEXT OUTPUT. Provided a list of duplicates, such as fdupes or fslint output, generate a bash script that will have all duplicates in protected directories commented out. If none of the protected duplicates are found in a set of the same files, select a random unprotected duplicate for preserving. Each path to a file will be transformed to an `rm "path"` string which will be printed to standard output. """ from optparse import OptionParser parser = OptionParser() parser.add_option("-k", "--keep", dest="keep", help="""List of directories which you want to keep, separated by commas. \ EXAMPLE: exclude_duplicates.py --keep /path/to/directory1,/path/to/directory\ with\ space\ in\ path2""", metavar="keep" ) parser.add_option("-d", "--delimiter", dest="delimiter", help="Delimiter of duplicate file groups", metavar="delimiter" ) parser.add_option("-f", "--file", dest="file", help="List of duplicate file groups, separated by delimiter, for example, fdupes or fslint output.", metavar="file" ) (options, args) = parser.parse_args() directories_to_keep = options.keep.split(",") file = options.file delimiter = options.delimiter pretty_line = "\n#" + "-" * 35 print "#/bin/bash" print "#I will protect files in these directories:\n" for d in directories_to_keep: print "# " + d print pretty_line protected_set = set() group_set = set() def clean_set(group_set, protected_set, delimiter_line): not_protected_set = group_set - protected_set while not_protected_set: if len(not_protected_set) == 1 and len(protected_set) == 0: print "#randomly selected duplicate to keep:\n#rm "%s"" % not_protected_set.pop().strip("\n") else: print "rm "%s"" % not_protected_set.pop().strip("\n") for i in protected_set: print "#excluded file in protected directory:\n#rm "%s"" % i.strip("\n") print "\n#%s" % delimiter_line file = open(file, "r") for line in file.readlines(): if line.startswith(delimiter): clean_set(group_set, protected_set, line) group_set, protected_set = set(), set() else: group_set = group_set|{line} for d in directories_to_keep: if line.startswith(d): protected_set = protected_set|{line} else: if line: clean_set(group_set, protected_set, line)  

결과 remove-duplicate-files-keep-protected.sh 파일에는 보호 된 디렉토리의 모든 파일이 주석 처리되어 있습니다.이 파일을 좋아하는 텍스트 편집기에서 열고 모든 것이 정상인지 확인한 다음 실행하십시오. Voila (sic)!

의견

  • 생각했지만 ‘ 충분히 자동화되지 않았습니다. 어리석게도이 방법으로 데이터 손실이 발생했습니다. 여러 파일 시스템에 걸쳐있는 중복을 처리합니다 … fdup의 출력이 주어지면 ‘ 우선 순위를 할당 할 방법이 없습니다. es. 기본적으로 데이터 손실을 방지하기 위해 10000 개의 파일을 직접 검색해야했을 것입니다. 그러니 고맙습니다 … 사실, 데이터 손실이 제가이 질문을 한 바로 그 이유입니다.
  • @ixtmixilix, 음, 수동 방법은 사용자의주의에 따라 달라집니다. ‘ 새로운 것은 없습니다. 더 자동화 된 기능을 원하면 위의 업데이트 된 답변을 확인하세요.

답변

이렇게하면 어떻습니까?

#!/bin/bash DUPE_SEARCH_DIR=somedir/ PREFERRED_DIRS=("somedir/subdir1" "somedir/subdir2") DUPE_FILE=/tmp/`basename $0`_found-duplicates delete_dupes() { while read line ; do if [ -n "$line" ] ; then matched=false for pdir in "${PREFERRED_DIRS[@]}" ; do if [[ $line == $pdir/* ]] ; then matched=true break fi done if ! $matched ; then rm -v "$line" fi fi done < "$DUPE_FILE" } cleanup() { rm -f $DUPE_FILE } trap cleanup EXIT # get rid of normal dupes, preserve first & preserve preferred fdupes -rf "$DUPE_SEARCH_DIR" > $DUPE_FILE delete_dupes # get rid of preserve dupes, preserve preferred fdupes -r "$DUPE_SEARCH_DIR" > "$DUPE_FILE" delete_dupes 

답변

APFS (Apple Filesystem) 기준, 또 다른 솔루션 파일을 보관하고 중복 제거하며 디스크 사용에 영향을주지 않는 것입니다. APFS의 기존 중복 파일을 복제본으로 바꾸기

를 참조하십시오.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다