Tìm và xóa các tệp trùng lặp trong osx bằng một tập lệnh


11

Từ: http://www.chriswrites.com/2012/02/how-to-find-and-delete-d repeatate-files-in-mac-os-x / Làm cách nào để sửa đổi điều này để chỉ xóa phiên bản đầu tiên của tập tin nó nhìn thấy.

Mở Terminal từ Spotlight hoặc thư mục Tiện ích Thay đổi thư mục (thư mục) bạn muốn tìm kiếm (bao gồm các thư mục con) bằng lệnh cd. Tại dấu nhắc lệnh gõ cd, ví dụ cd ~ / Documents để thay đổi thư mục vào thư mục Tài liệu tại nhà của bạn Tại dấu nhắc lệnh, nhập lệnh sau:

find . -size 20 \! -type d -exec cksum {} \; | sort | tee /tmp/f.tmp | cut -f 1,2 -d ' ' | uniq -d | grep -hif  /tmp/f.tmp > duplicates.txt

Phương pháp này sử dụng tổng kiểm tra đơn giản để xác định xem các tệp có giống nhau không. Tên của các mục trùng lặp sẽ được liệt kê trong một tệp có tên trùng lặp.txt trong thư mục hiện tại. Mở cái này để xem tên của các tệp giống hệt nhau Hiện có nhiều cách khác nhau để xóa các bản sao. Để xóa tất cả các tệp trong tệp văn bản, tại dấu nhắc lệnh:

while read file; do rm "$file"; done < duplicates.txt

Câu trả lời:


4

Đầu tiên, bạn sẽ phải sắp xếp lại dòng lệnh đầu tiên để thứ tự các tệp được tìm thấy bởi lệnh find được duy trì:

find . -size 20 ! -type d -exec cksum {} \; | tee /tmp/f.tmp | cut -f 1,2 -d   | sort | uniq -d | grep -hif  /tmp/f.tmp > duplicates.txt

(Lưu ý: cho mục đích thử nghiệm trong máy tôi đã sử dụng find . -type f -exec cksum {} \;)

Thứ hai, một cách để in tất cả trừ bản sao đầu tiên là sử dụng tệp phụ trợ, giả sử /tmp/f2.tmp. Sau đó, chúng ta có thể làm một cái gì đó như:

while read line; do
    checksum=$(echo "$line" | cut -f 1,2 -d' ')
    file=$(echo "$line" | cut -f 3 -d' ')

    if grep "$checksum" /tmp/f2.tmp > /dev/null; then
        # /tmp/f2.tmp already contains the checksum
        # print the file name
        # (printf is safer than echo, when for example "$file" starts with "-")
        printf %s\\n "$file"
    else
        echo "$checksum" >> /tmp/f2.tmp
    fi
done < duplicates.txt

Chỉ cần đảm bảo rằng nó /tmp/f2.tmptồn tại và trống trước khi bạn chạy nó, ví dụ thông qua các lệnh sau:

rm /tmp/f2.tmp
touch /tmp/f2.tmp

Hy vọng điều này sẽ giúp =)


39

Một tùy chọn khác là sử dụng fdupes:

brew install fdupes
fdupes -r .

fdupes -r .tìm các tệp trùng lặp đệ quy trong thư mục hiện tại. Thêm -dđể xóa các bản sao - bạn sẽ được nhắc giữ những tập tin nào; nếu thay vào đó bạn thêm -dN, fdupes sẽ luôn giữ tệp đầu tiên và xóa các tệp khác.


7
fdupesnó thật tuyệt! Làm việc như người ở! Cảm ơn bạn.!
racl101

3

Tôi đã viết một tập lệnh đổi tên các tập tin của bạn để khớp với hàm băm của nội dung của chúng.

Nó sử dụng một tập hợp con các byte của tệp để nó nhanh và nếu có xung đột, nó sẽ nối một bộ đếm với tên như thế này:

3101ace8db9f.jpg
3101ace8db9f (1).jpg
3101ace8db9f (2).jpg

Điều này giúp bạn dễ dàng tự mình xem xét và xóa các bản sao mà không cần tin tưởng vào phần mềm của người khác với ảnh của bạn nhiều hơn bạn cần.

Tập lệnh: https://gist.github.com/SimplGy/75bb4fd26a12d4f16da6df1c4e506562

nhập mô tả hình ảnh ở đây


+1 chỉ cho màn hình GIF !!
NoobEditor

0

Điều này được thực hiện với sự trợ giúp của ứng dụng EagleFiler, được phát triển bởi Michael Tsai .

tell application "EagleFiler"

      set _checksums to {}
      set _recordsSeen to {}
      set _records to selected records of browser window 1
      set _trash to trash of document of browser window 1
      repeat with _record in _records
          set _checksum to _record's checksum
          set _matches to my findMatch(_checksum, _checksums, _recordsSeen)
          if _matches is {} then
              set _checksums to {_checksum} & _checksums
              set _recordsSeen to {_record} & _recordsSeen
          else
              set _otherRecord to item 1 of _matches
              if _otherRecord's modification date > _record's modification date 
then

            set _record's container to _trash
            else
                set _otherRecord's container to _trash
                set _checksums to {_checksum} & _checksums
                set _recordsSeen to {_record} & _recordsSeen
            end if
        end if
    end repeat
end tell

on findMatch(_checksum, _checksums, _recordsSeen)

    tell application "EagleFiler"
        if _checksum is "" then return {}
        if _checksums contains _checksum then
            repeat with i from 1 to length of _checksums
                if item i of _checksums is _checksum then
                    return item i of _recordsSeen
                end if
            end repeat
        end if
        return {}
    end tell

end findMatch

Bạn cũng có thể tự động xóa các bản sao với loại bỏ tệp trùng lặp được đề xuất trong bài viết này .


1
(1) Thế nào là Eagle EagleFiler? Nó có phải là một phần của macOS không? Nếu không, bạn lấy nó ở đâu? (2) Điều đó có nghĩa là một khối mã dài (theo cách tôi đã sửa nó)? (3) Hãy sửa chữa vết lõm của bạn. (4) Chính xác thì người ta sử dụng cái này như thế nào?
Scott
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.