rsnapshot
동일한 디렉토리 구조의 여러 스냅샷을 포함하고 동일한 파일이 모두 하드 링크로 대체된 디렉토리 트리가 생성되었습니다 .
이러한 하드 링크 중복 항목을 모두 제거하고 각 파일의 복사본 하나만 보관하고 싶습니다. 그러면 나중에 동일한 파일을 두 번 건드릴 필요 없이 모든 파일을 정렬된 아카이브로 이동할 수 있습니다.
이 작업을 수행할 수 있는 도구가 있나요?
지금까지 중복 항목을 찾을 수 있는 도구만 찾았습니다.만들다이를 대체할 하드 링크...
모든 파일과 해당 inode 번호를 나열하고 중복 제거 및 삭제를 직접 구현할 수 있다고 생각하지만 여기서는 바퀴를 재발명하고 싶지 않습니다.
답변1
마지막으로, 이 작업을 수동으로 수행하는 것은 그리 어렵지 않습니다.스티븐의그리고제노이드 같은팁과 몇 가지 사전 경험 find
.
FreeBSD의 GNU가 아닌 도구와 함께 작동하려면 일부 명령을 조정해야 했습니다. GNU에는 이를 대체할 수 있는 옵션이 find
있지만 FreeBSD는 그렇지 않습니다.-printf
-exec stat
find
# create a list of "<inode number> <tab> <full file path>"
find rsnapshots -type f -links +1 -exec stat -f '%i%t%R' {} + > inodes.txt
# sort the list by inode number (to have consecutive blocks of duplicate files)
sort -n inodes.txt > inodes.sorted.txt
# remove the first file from each block (we want to keep one link per inode)
awk -F'\t' 'BEGIN {lastinode = 0} {inode = 0+$1; if (inode == lastinode) {print $2}; lastinode = inode}' inodes.sorted.txt > inodes.to-delete.txt
# delete duplicates (watch out for special characters in the filename, and possibly adjust the read command and double quotes accordingly)
cat inodes.to-delete.txt | while read line; do rm -f "$line"; done
답변2
여러 링크가 있는 인덱스 노드를 찾으려면 다음을 수행하십시오.
find . -exec stat -c '%i' {} \; | sort -n | uniq -d
그런 다음 해당 목록을 반복할 수 있습니다.
find -inum {inode_number}
이 inode를 공유하는 파일을 나열합니다. 어느 것을 삭제할지는 귀하에게 달려 있습니다.
답변3
모든 파일이 단일 디렉터리 계층 구조의 하드 링크만 갖고 있다는 것을 알고 있다면 간단히 다음을 수행할 수 있습니다.
find inputdir -type f -links +1 -exec rm {} \;
그 이유는 rm {} \;
파일을 즉시 삭제하면 stat()
1개 이상의 개수가 반환되기 때문입니다. 따라서 동일한 inode의 다른 부분의 하드링크 개수는 1씩 감소하게 되며 해당 파일이 유일한 복사본인 경우 rm
마지막 파일에서 find 실행 시 해당 파일에 대해서는 find가 실행되지 않습니다 stat()
.
파일에 inputdir
이 명령 외부의 하드 링크 복사본이 있는 경우 주의하세요.모든 사본이 삭제됩니다.계층 구조 내에서 inputdir
!