파일이 동일한 이름을 공유하는 경우에만 중복 항목을 제거하고 싶습니다.
예: rdfind -deleteduplicates true ~/folder
내 목표는 달성되지 않을 것입니다.
한 가지 아이디어는 rdfind 시험 실행의 출력(results.txt)을 얻는 것입니다.
rdfind -n true "$PWD"
다음으로 시작하여 식별되는 각 그룹의 첫 번째 파일과 동일한 이름을 가진 파일을 확인합니다.DUPTYPE_FIRST_OCCURRENCE XXXX
DUPTYPE_FIRST_OCCURRENCE 5148 2 37934240 2054 16916792 1 /home/fig3.tif
DUPTYPE_WITHIN_SAME_TREE -5148 3 37934240 2054 17044654 1 /home/other/fig3.tif
DUPTYPE_WITHIN_SAME_TREE -5148 3 35435435 2054 16546546 1 /home/other2/fig3.tif
DUPTYPE_FIRST_OCCURRENCE 5160 2 116397930 2054 16916804 1 /home/file.psd
DUPTYPE_WITHIN_SAME_TREE -5160 2 116397930 2054 16916870 1 /home/folder/file.psd
DUPTYPE_WITHIN_SAME_TREE -5160 2 116397930 2054 17654654 1 /home/folder/file2.psd
위의 예에서 첫 번째 그룹의 경우 중복 항목 2개를 제거해야 하고, 두 번째 그룹에서는 첫 번째 항목과 이름이 동일한 중복 항목 하나만 제거해야 합니다(file.psd).
편집 : rmlint의 답변이 바람직합니다. "원시" 파일은 일반적으로 다음을 사용하여 생성할 수 있습니다.린트
답변1
results.txt
rdfind
이 스크립트는 질문에 표시된 대로 생성된 파일을 사후 처리합니다 .
#!/bin/bash
#
while read -r type x x x x x x path
do
case "$type" in
DUPTYPE_FIRST_OCCURRENCE)
name="${path##*/}"
echo "New path for $name" >&2
;;
DUPTYPE_WITHIN_SAME_TREE|DUPTYPE_OUTSIDE_TREE)
if [[ -n "$name" ]] && [[ ${path##*/} == $name ]]
then
echo "Remove duplicate $path" >&2
# rm -f "$path"
else
echo "Skipping differently named $path" >&2
fi
;;
esac
done
rm
작업을 수행할 준비가 되면 주석 처리를 해제하세요. echo
명령문을 주석 처리 하거나 리디렉션합니다.표준 에러) 장황한 내용을 원하지 않는 경우.
read -r type x x x x x x path
루프 상단의 명령문은 공백으로 구분된 8개의 필드를 읽습니다. 가운데 6개는 관련이 없으므로 가비지 변수로 읽어들여 합계만 사용 $type
합니다 $path
.
생산하다results.txt
rdfind -dryrun true -makeresultsfile true {directory...}
생성된 파일의 후처리( rddedup
위에 표시된 내 스크립트입니다)
rddedup < results.txt
답변2
이 고양이의 가죽을 다른 방법으로 벗기는 방법은 무엇입니까? ( rmlint
이 글을 게시하려고 할 때 OP 편집 요청이 이루어졌지만 신경 쓰지 마세요. 이것도 게시될 수 있습니다...하단의 편집을 참조하세요 rmlint
)
구조가 알려져 있으므로 파일 이름의 첫 번째 발생이 대상이고 빈 줄이 제거되기 전의 후속 중복이므로 awk
@roaima보다 약간 느리기는 하지만 재미있을 수도 있습니다.
awk 'NF==0{getline; target=""}
target==""{l=split($8,t,"/"); target=t[l];getline}
{l=split($8,q,"/");if (q[l]==target)print $8}' file1 | while read f; do echo rm $f ; done
송곳
빈 줄이 있으면 건너뛰고 대상 파일 이름을 다음으로 재설정하세요.""
awk 'NF==0{getline; target=""}
대상이 설정되지 않은 경우(즉, 각 빈 줄 뒤와 시작 부분) 이 줄에서 대상 파일 이름을 가져와 다음 줄로 이동합니다.
target==""{l=split($8,t,"/"); target=t[l];getline}
이제 현재 줄의 파일 이름을 대상과 비교하여 일치하는 경우 전체 경로를 출력합니다.
{l=split($8,q,"/");if (q[l]==target)print $8}' file1
그런 다음 루프를 통해 awk
실제 삭제(삭제만)를 수행합니다 .echo
| while read f; do echo rm $f ; done
이 작업을 수행할 수도 있지만 (다시 삭제하면 됩니다 echo
)
{l=split($8,q,"/");if (q[l]==target)print $8}' file1 | xargs echo rm
편집하다우수한rmlint
앞은 당신이 쉽게 통제할 수 없는 우선순위인 것 같아요독창성
기본적으로 rmlint 명령에 여러 경로를 지정하면 첫 번째 명명된 경로의 파일이 나중에 명명된 경로보다 더 "원본"인 것으로 간주됩니다. 동일한 경로에 두 개의 파일이 있는 경우 이전 파일이 원본 파일로 간주됩니다. 수정 시간이 동일한 경우 어느 것이 원본으로 선택되는지는 단지 우연의 문제입니다.
그러나 명시적인 예의 경우 이 옵션(원래 파일 계층 구조에서 가장 낮은 수준)은 콘텐츠가 아닌 파일 이름을 기준으로 한 일치 -d
와 함께 사용됩니다 .-b
rmlint -d -b /home/
틀림없이 이것은많은내 스크립트보다 짧지만 rmlint
스크립트를 작성하는 것보다 페이지를 읽는 데 시간이 더 걸립니다. 골라보세요.
테스트되지 않은, btw ...
답변3
다음은 중복 항목이 서로 일치하지만 주어진 파일 목록의 첫 번째 항목이 아닌 상황에 대해 수정된 roaima의 스크립트입니다. 예를 들어. 동일한 파일에는 a/x
, , b/y
의 세 가지 이름이 있습니다 c/y
. 그런 다음 a/x
기본 파일( DUPTYPE_FIRST_OCCURRENCE
)이 제거되면 다른 파일 중 하나가 삭제됩니다.
#!/bin/bash
while read -r type x x x x x x path
do
name="${path##*/}"
[[ "$type" == '#' ]] || [[ -z "$name" ]] &&
printf "%s\n" "skipping a non-entry looking line">&2
case "$type" in
DUPTYPE_FIRST_OCCURRENCE)
printf "New path for %s: %s\n" "$name" "$path">&2
unset ass
declare -A ass
ass["$name"]=1
;;
DUPTYPE_WITHIN_SAME_TREE|DUPTYPE_OUTSIDE_TREE)
if [ "${ass["$name"]}"x != "x" ]
then
printf "Remove duplicate: %s\n" "$path" >&2
# rm -f "$path"
else
ass["$name"]=1
printf "Skipping differently named file: %s\n" "$path" >&2
fi
;;
esac
done < results.txt
일부 다른 변경 사항이 포함되어 있으며 주석 없이 읽을 수 있습니다. ass
연관 배열입니다.
이 스크립트는 완전히 테스트되지 않았으므로 아직 해결되지 않은 특수 사례가 있을 수 있다는 점을 인정해야 합니다.
사용 예. rdfind -n true .
그러면 우리는 이것을 얻습니다:
$ ls *
results.txt script.bash
a:
filea0 filea1 fileb0
b:
filea1 fileb0
c:
fileb0
결과.txt:
$ cat results.txt
# Automatically generated
# duptype id depth size device inode priority name
DUPTYPE_FIRST_OCCURRENCE 4 1 6 64773 4849814 3 ./a/filea0
DUPTYPE_WITHIN_SAME_TREE -4 1 6 64773 4849816 3 ./b/filea1
DUPTYPE_WITHIN_SAME_TREE -4 1 6 64773 4849817 3 ./a/filea1
DUPTYPE_FIRST_OCCURRENCE 6 1 6 64773 4849677 3 ./a/fileb0
DUPTYPE_WITHIN_SAME_TREE -6 1 6 64773 4849819 3 ./b/fileb0
DUPTYPE_WITHIN_SAME_TREE -6 1 6 64773 4986586 3 ./c/fileb0
# end of file
실행 중인 스크립트:
./script.bash
skipping a non-entry looking line
skipping a non-entry looking line
New path for filea0: ./a/filea0
Skipping differently named file: %s\n ./b/filea1
Remove duplicate: ./a/filea1
New path for fileb0: ./a/fileb0
Remove duplicate: ./b/fileb0
Remove duplicate: ./c/fileb0
skipping a non-entry looking line