중복 파일 찾기

6376 단어 GoLinuxfdupestech
여기서 말한 중복 파일 이름과 다르지만 내용은 같은 파일입니다
어떻게 찾습니까?그렇다면 어디까지 해야 할지 고민을 해봤어요

TL;DR

  • 중복 파일을 검색하는 명령fdupes을 사용하면 기본적으로 OK
  • 빠른 처리만 생략하는 방법
  • 이 있다

    중복 파일 찾기


    우선 아래의 문건을 고려하다
    $ ls -l
    total 20
    -rw-r--r-- 1 root root    1 May  6 00:53 a.dat
    -rw-r--r-- 1 root root    2 May  6 00:53 b.dat
    -rw-r--r-- 1 root root 1024 May  6 01:00 c.dat
    -rw-r--r-- 1 root root 1024 May  6 01:00 d.dat
    -rw-r--r-- 1 root root 1024 May  6 01:00 e.dat
    
    만약 이런 느낌이 매우 작은 파일이라면, 아래와 같이 모든 파일의 산열을 계산할 수 있지만, 나는 방법을 생각해 보겠다
    (해시 값의 계산은md5와sha-1 모두 가능하지만 fdupes와 마찬가지로 가벼운md5로 계산한다)
    $ md5sum * | perl -nalE 'push(@{$u{$F[0]}},$F[1])}{for(keys %u){say"@{$u{$_}}"if@{$u{$_}}>1}'
    c.dat e.dat
    
    우선, a.dat, b.dat에 관해서는 파일 크기가 각각 1byte, 2byte이기 때문에 계산하지 않아도 독특하다고 느낄 수 있다
    다음은 c.dat, d.dat, e.dat의 해시 값을 계산하기 전에 시작하는 10byte만 계산한다
    $ head -c 10 c.dat | md5sum
    f6513d74de14a6c81ef2e7c1c1de4ab1  -
    $ head -c 10 d.dat | md5sum
    660f54f5a7658cbf1462b2a91fbe7487  -
    $ head -c 10 e.dat | md5sum
    f6513d74de14a6c81ef2e7c1c1de4ab1  -
    
    이렇게 하면 d.dat이 독특해요.
    이처럼 갑자기 전체를 계산하는 것이 아니라 처음 Xbyte를 먼저 계산해 비교하면 비교적 빠를 수 있다.
    예를 들어 c.dat, d.dat가 10Gbyte 파일이라면 해시 계산은 20Gbyte를 읽어야 한다
    만약 시작 10byte 내에 차이가 있다면 읽는 데이터가 20byte에 불과하기 때문에 대폭 빨라질 것이다.
    fdupes가 먼저 계산한 것 같다최초의 4096 byte.
    따라서4096 byte에서 차이가 있으면 처리가 빠르게 진행됩니다.
    fist-step
    다만, 같은 사이즈로 시작하는 100kbyte 정도가 같으면 같은 확률이 높다.
    그렇게 정확하지 않더라도 빨리 보여줬으면 해서 직접 해봤어요
    fdupes의 issue가 정확하지 않아도 시작 Xbyte로 끝내는 게 어때요?누가 그러시긴 하지만.
    정확한게 아니라 위험해서 fdupes에 들어갈 수 없습니다
    https://github.com/adrianlopezroche/fdupes/issues/79
    jdupes면 fdupes만으로는 완료할 수 없는 시작 4096byte로 중복 파일을 판단하는 옵션(-TT 옵션)
    사용해 봤는데 4096 byte가 처리를 멈추면 자기 환경 중 일부 미디어 파일에 버그 감지가 있어서 이번엔 혼자 할 필요 없어

    이루어지다


    이렇게 하는 거예요.
    https://github.com/yaasita/chofuku
    이번에 SQLite 메모리 모드를 사용했는데 중복 수만 있으면 돼요.
    우선, 이름과 서류를 기록한다.
    이번에는 하드웨어 링크를 고려한 적이 없지만 이럴 때 i-node 번호를 기록할 수 있고 같은 것은 해시 계산을 하지 않으면 된다.기호 링크도 건너뛰고 있습니다.
    SELECT * FROM files;
    
    name
    size
    head100k_hash
    full_hash
    a.dat
    1
    b.dat
    2
    c.dat
    1024
    d.dat
    1024
    e.dat
    1024
    f.dat
    1150976
    g.dat
    1150976
    h.dat
    1150976
    다음 SQL 카운트를 사용하여 반복(반복 시 항상 이 쿼리 사용)
    SELECT size, head100k_hash, full_hash, json_group_array(name) FROM files GROUP BY size, head100k_hash, full_hash HAVING count(*) > 1;
    
    size
    head100k_hash
    full_hash
    json_group_array(name)
    1024
    ["c.dat","d.dat","e.dat"]
    1150976
    ["f.dat","g.dat","h.dat"]
    같은 크기의 파일을 나열했습니다.
    -size-only 옵션을 지정하면 여기서 처리를 중지합니다.
    이어서 같은 크기의 파일 시작 100kbyte의 해시 값을 계산합니다
    0byte 파일이 해시 컴퓨팅 건너뛰기
    name
    size
    head100k_hash
    full_hash
    a.dat
    1
    b.dat
    2
    c.dat
    1024
    2f2bf74e24d26a2a159c4f130eec39ac
    d.dat
    1024
    fc65c6cb47f6eed0aa6a34448a8bfcec
    e.dat
    1024
    2f2bf74e24d26a2a159c4f130eec39ac
    f.dat
    1150976
    595cd4e40357324cec2737e067d582b1
    g.dat
    1150976
    595cd4e40357324cec2737e067d582b1
    h.dat
    1150976
    595cd4e40357324cec2737e067d582b1
    동일 계수 중복
    SELECT size, head100k_hash, full_hash, json_group_array(name) FROM files GROUP BY size, head100k_hash, full_hash HAVING count(*) > 1;
    
    size
    head100k_hash
    full_hash
    json_group_array(name)
    1024
    2f2bf74e24d26a2a159c4f130eec39ac
    ["c.dat","e.dat"]
    1150976
    595cd4e40357324cec2737e067d582b1
    ["f.dat","g.dat","h.dat"]
    - 100k-only 옵션을 지정하면 여기서 처리를 중지합니다.
    모든 파일의 해시 값 계산하기
    100Kbyte 미만 파일 건너뛰기 계산
    해시 값 계산 부분은 병행화할 수 있지만, 파일을 열 수 있는 한계값 (ulimit-n의 값) 을 초과하지 않아야 합니다.
    이번에는 순서대로 했어요.
    name
    size
    head100k_hash
    full_hash
    a.dat
    1
    b.dat
    2
    c.dat
    1024
    2f2bf74e24d26a2a159c4f130eec39ac
    d.dat
    1024
    fc65c6cb47f6eed0aa6a34448a8bfcec
    e.dat
    1024
    2f2bf74e24d26a2a159c4f130eec39ac
    f.dat
    1150976
    595cd4e40357324cec2737e067d582b1
    ca2e51ae14747a1f1f0dcb81e982c287
    g.dat
    1150976
    595cd4e40357324cec2737e067d582b1
    067d1eed705e0f7756ceb37a10462665
    h.dat
    1150976
    595cd4e40357324cec2737e067d582b1
    ca2e51ae14747a1f1f0dcb81e982c287
    출력 반복
    SELECT size, head100k_hash, full_hash, json_group_array(name) FROM files GROUP BY size, head100k_hash, full_hash HAVING count(*) > 1;
    
    size
    head100k_hash
    full_hash
    json_group_array(name)
    1024
    2f2bf74e24d26a2a159c4f130eec39ac
    ["c.dat","e.dat"]
    1150976
    595cd4e40357324cec2737e067d582b1
    ca2e51ae14747a1f1f0dcb81e982c287
    ["f.dat","h.dat"]
    파일 전체를 산열하려면 fldupes를 사용하는 것이 더 빠릅니다
    만약 -100k-only 또는 -size-only를 지정하지 않는다면 이 프로그램을 사용하는 것은 무의미하다
    (단, 나는 -Size-only는 실용적으로 사용할 수 없다고 생각한다.)

    총결산


    이렇게 100kbyte로 산열 계산을 끝내는 것도 fdupes의 결과와 같다.
    그러나 이것은 단지 자신의 환경이기 때문에 세계에도 100kbyte를 공통 헤더로 사용하는 파일이 있을 수 있다.상황에 맞게 방법을 바꾸는 게 좋을 것 같아요.
    대부분 fdupes에서 하면 돼요.
    중복 제거는 데이터 감축zfsbtrfs 등 파일 시스템에서도 사용할 수 있다.(많은 메모리 필요)
    만약 URI가 해시치ipfs라면 같은 파일을 가진 사람을 인터넷에서 찾을 수 있는데 이걸 활용하면 재밌을 것 같아요.

    좋은 웹페이지 즐겨찾기