티스토리 뷰

파일 해시값을 바탕으로 중복파일 제거하기 및 이에 따른 파일관리 요령


주의 사항

파일 관련작업은 언제나 신중해야한다

모든 명령과 행동에 대해 실행 전에 심사숙고해라

이 글은 이 과정을 진행하면서 당신이 경험하게 될 그 어떤 실수에 대해서 책임 지지않는다


gather.da12536949dd9dddfc21dbdb5568c829.py

스크립트 파일을 첨부했다. 다운받아서 쓰면 된다.


이것은 지정한 폴더 안에 파일들 하나하나의 HASH 값을 구해서 파일이 중복되지 않는 상태로 보관하기 위한 스크립트이다

주의할 점은 이 스크립트는 디렉토리구조는 날려버리는 특징이 있으므로 디렉토리구조도 중요하게 보존되어야하는 경우는 사용을 금지한다

즉 파일 서로서로가 의존적인 형태가 아닌 파일 하나하나가 독립적으로 의미를 가지는 경우에 사용하는것이 좋다.


구체적인 사용방법에 대해서 기술하겠다

본 작업은 Linux 나 macOS 에서 하는것을 권장한다

먼저 상황을 그려보자 /Volumes/hdd1/ 라는 폴더가 있고 이 안에 무수히 많은 파일들이 존재한다고 가정하자


1. 파일 한데 모으기

이 과정에서 디렉토리 트리구조가 제거되므로 조심하자

cd /Volumes/hdd1/;

mkdir ./data/; # data 라는 폴더가 기존에 없는지 확인하고 하자

mv * ./data/; # 모두 옮긴다. data 폴더는 옮길수 없다는 에러가 뜬다만 무시하자.

python gather.py -gather data gathered 3000 0 # data 폴더에 있는 파일들을 gathered 폴더로 모두 이동한다는 의미이다.


2. 파일의 HASH값 구하기

HASH 값이란 파일의 ID 라고 이해하면 된다.

gathered 폴더에 있는 파일들의 hash-id 를 구해서 unique 폴더 안에 id 별로 정리해서 파일들을 이동시킨다

예를들어 ID가 5c36b7b402ea944a623d73ab8798dbd8 인 파일은 

./unique/5c3/5c36b7b402ea944a623d73ab8798dbd8/ 안에 위치하게된다.

파일이름이 abc.JPG 라면 abc.JPG.150669389933_20150301235614.jpg 의 모양으로 이름이 변경된다

만약 중복되는 파일이 존재한다면 이 폴더에 모이게된다.

1099511627776 는 1테라바이트라는 의미이고 이게 뭐냐면 이 용량보다 큰 파일은 손대지 않겠다는 의미이다

이 커맨드는 데이터 량에 따라 오래걸릴 수도 있다

python gather.py -genhash gathered unique 1099511627776 


모두 정리가 되면 사진과 같은 모양이 된다.

같은 폴더안에 모이게 되는 파일들은 모두 실제 내용이 동일한 파일들이다.

즉 중복되는 파일들이다.



3. 중복되는 파일의 분류

중복되는 파일이 여러개 존재한다면 단 한개만을 남겨두고 따로 다른 장소(휴지통같은곳)로 분리한다

명령을 수행하고나면 remove_5c36b7b402ea944a623d73ab8798dbd8 이런 이름의 폴더가 생길것이다.

이 폴더를 휴지통이라고 이해하면 된다

python gather.py -rmd unique 1000


4. 휴지통 비우기

echo '' >> remove_5c36b7b402ea944a623d73ab8798dbd8.txt;

python gather.py -flush remove_5c36b7b402ea944a623d73ab8798dbd8 unique >> remove_5c36b7b402ea944a623d73ab8798dbd8.txt;

find remove_5c36b7b402ea944a623d73ab8798dbd8 -type d -exec rmdir {} \;

이렇게 해주면 휴지통이 비워지고 휴지통도 함께 날려버리고

날라간 파일들의 목록을 remove_5c36b7b402ea944a623d73ab8798dbd8.txt 에 누적 기록해준다


5. unique 파일목록 구조를 txt로 기록해두기

이걸 하는 이유는 파일을 검색하거나 할때 실제 파일 찾기를 하게되면 굉장히 오래걸리게된다.

그래서 이렇게 unique.list.txt 파일을 만들어두면 빠르게 검색할 수 있게된다.

python gather.py -listfile unique > unique.list.txt




unique 로 파일을 정리해두고 unique.list.txt 를 떠둔 상황에서 파일의 조회 방법을 상황별로 설명하고자 한다


# 확장자가 jpeg 인 파일들을 출력한다

cat unique.list.txt | grep -i $'^jpeg\t' | awk -F " " '{print $3}';


# 확장자가 jpeg 인 파일들 중 파일 이름에 fullsize 라는 문자열이 들어간 것만 추린다

cat unique.list.txt | grep -i $'^jpeg\t' | awk -F " " '{print $3}' | grep fullsize;


# 확장자가 jpeg 인 파일들의 갯수를 센다

cat unique.list.txt | grep -i $'^jpeg\t' | wc -l;


# 확장자가 jpeg 인 파일들의 용량의 총합을 계산한다

sizeList=(`cat unique.list.txt | grep -i $'^jpeg\t' | awk -F " " '{print $2}'`);accumulate=0; for size in "${sizeList[@]}"; do accumulate=$(($size+$accumulate)); done ; echo $(($accumulate/1024/1024))' MB';


# 확장자가 jpeg 인 파일들 중 파일이름에 fullsize 라는 문자열이 들어간 파일들의 용량의 총합을 계산한다

sizeList=(`cat unique.list.txt | grep -i $'^jpeg\t' | grep fullsize | awk -F " " '{print $2}'`);accumulate=0; for size in "${sizeList[@]}"; do accumulate=$(($size+$accumulate)); done ; echo $(($accumulate/1024/1024))' MB';


# 확장자가 mp4 이거나 mp3 인 파일중 에서 파일이름에 a가 포함된 것 중에서 용량이 5000바이트보다 작은것 출력

python gather.py -filework unique.list.txt '\.mp3$|\.mp4$&a' unique '<5000' echo ''


# 확장자가 mp4 이거나 mp3 인 파일중 에서 파일이름에 a가 포함된 것 출력

python gather.py -filework unique.list.txt '\.mp3$|\.mp4$&a' unique '00' echo ''


# 파일이름에 abc 이면서 def 가 포함되는거 출력

python gather.py -filework unique.list.txt 'abc&def' unique '00' echo ''


# 파일이름에 abc 이면서 def 가 포함되는거 의 총 파일용량 합계 출력

echo $((`python gather.py -filework unique.list.txt 'abc&def' unique '00' totalsize '' | sed 's/^.* //g'`/1024/1024))' MB'


# 파일이름에 abc 이면서 def 가 포함되는거 XXXaadfasdf/5 폴더로 카피 (Copy Completly Done 메세지가 떠야 제대로 카피된거다)

python gather.py -filework unique.list.txt 'abc&def' unique '00' cp 'XXXaadfasdf/5'


# 빈폴더들 제거

find folder -type d -exec rmdir {} \;




그외. 파일카피 하는 요령

상황: /Volumes/FTR/FourTerra1/ 의 파일들을 /Volumes/FourTerra/FourTerra1/ 로 카피하고자 한다


1. 파일카피를 한다.

cp -r /Volumes/FTR/FourTerra1/ /Volumes/FourTerra/FourTerra1/;


2. 디스크 언마운트하고 디스크의 전원공급도 차단한다


3. 다시 디스크의 전원 올리고 마운트한다


4. 사본에서 누락분이 있는지 체크 후, 있다면 따로 카피해두기

일단 카피를 했는데 누락분이 생기는 경우는 굉장히 미스테리한 경우이지만 내가 그런 경우를 겪었다. 이유는 여전히 모른다.


sudo su # 일단 루트로 들어와주세요

#---------------------------------------------------------------------------

SOURCE=/Volumes/FTR/FourTerra1/        # 원본데이터가 담긴 경로를 써주세요

DESTIN=/Volumes/FourTerra/FourTerra1/  # 사본데이터가 담긴 경로를 써주세요

COPIED=copied2                         # 원본데이터쪽에만 존재하고 사본데이터쪽에는 존재하지 않는 파일을 카피해 넣을 폴더의 이름을 정해주세요

RESULT=result.txt                      # 처리결과 보고서로 저장할 파일 이름을 정해주세요

#---------------------------------------------------------------------------

SOUTXT=`echo $SOURCE | sed 's/\//_/g' | sed 's/$/.txt/g'`

DESTXT=`echo $DESTIN | sed 's/\//_/g' | sed 's/$/.txt/g'`

python gather.py -listfile $SOURCE > $SOUTXT;python gather.py -listfile $DESTIN > $DESTXT;

python gather.py -compare $DESTIN $DESTXT $SOUTXT $COPIED > ${RESULT};

TOTAL=`cat ${RESULT} | grep ^TOTAL | sed 's/^.* //g'`;

TOTAD=`cat ${RESULT} | grep ^TOTAD | sed 's/^.* //g'`;

if [[ -d $COPIED ]] && [ $TOTAL = $TOTAL ] && [ `find $COPIED -type f | wc -l` = `cat ${RESULT} | grep '^OKAY ' | wc -l` ] && [ `cat ${RESULT} | grep '^ERROR' | wc -l` = 0 ] && [ `cat ${RESULT} | grep '^NOEXI' | wc -l` = 0 ] ; then

   if [[ ! -d $COPIED'_'$TOTAL ]] ; then

      $(echo mv $COPIED $COPIED'_'$TOTAL);

      echo "정상적으로 처리되었습니다"

   fi

fi


#----------

# 최종적으로 정상적으로 처리되었습니다 메세지가 나와야 잘 된거다

# 이 메세지가 나오지 않는다면 제대로 처리되지 않은것이다.

# 만약 누락분중 동일한 이름의 파일이 중복될경우 정상처리되지 않게된다

댓글
댓글쓰기 폼
공지사항
Total
32,109
Today
30
Yesterday
15
링크
«   2018/11   »
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  
글 보관함