2012-02-04 2 views

ответ

3

cmp может использоваться для сравнения двоичных файлов.

cmp file1.mp3 file2.mp3 
if [[ $? -eq 0 ]]; then echo "Matched"; fi 

cmp команда возвращает 0 если файлы одинаковые или еще -1.

+0

благодарственное вы это прекрасно. Если бы я решил адаптировать мой код для сравнения всех типов файлов, могу ли я сделать что-то с вложенным циклом для сравнения всех файлов с помощью опции -t? – slev

+0

@slev Какой вариант '-t'? –

1

Если файлы действительно байт-байт-эквивалент, вы можете начать поиск файлов того же размера. Если их размер один и тот же, вы можете продолжить исследование (например, сравнить их md5sum). Если файлы содержат только одну песню, но используют другой кодек/сжатие/все, bash, вероятно, не подходит для этой задачи.

+0

haha ​​спасибо, мой следующий вопрос будет, если есть какой-либо подход с использованием хеш-карт. – slev

0

Я использую этот скрипт для своей фотографии, но его можно использовать для других файлов.

  • Сначала я передать фотографии из моих телефона/камер в каталог newfiles
  • Затем я запускаю этот скрипт из моих фотографий корневого каталога
    • При обнаружении дублированных файлов, скрипт сохраняет один файл и перемещает другие из них в каталог ../garbage
    • сценарий движется в приоритетном файле из newfiles

Внимание: Этот скрипт не сравнивает содержимое файла, но он обнаруживает файлы с одинаковым размером & (это нормально для файлов камеры). Мой другой ответ основан на сравнении содержания (md5sum).

#!/bin/bash 

# If a file from directory 'newfile' has same size & name 
# that another file from another directory 
# then moves the file from 'newfile' to 'garbage' 
find newfiles/ -type f -printf '%s %f\n' | 
while read SIZE f 
do 
    find . -name "$f" -size ${SIZE}c | 
    grep -v 'newfiles' && 
    find . -name "$f" -size ${SIZE}c -path '*newfiles*' -exec mv -v '{}' ../garbage ';' && 
    echo 
done 

# Detect all other duplicated files 
# Keep the first occurrence and moves all other to 'garbage' 
find . -type f -printf '%s %f\n' | 
    LC_ALL=C sort | #LC_ALL=C disables locale => sort is faster 
    uniq -dc  | #keep duplicates and count number of occurrences 
    while read n SIZE f 
    do 
    echo -e "\n_____ $n files\t$SIZE bytes\tname: $f" 
    find . -name "$f" -size ${SIZE}c | 
     head -n 1 | 
     xargs mv -v -t ../garbage 
    done 
2

Это первый из командной строки перечислены все файлы, имеющие одинаковый размер и тот же md5sum из текущего каталога

find . -type f -printf '%11s ' -exec md5sum '{}' ';' | 
    sort | uniq -w44 --all-repeated=separate 

Вторая командная строка

  • быстрее, потому что он вычисляет md5sum исключительно для файлов с одинаковым размером
  • надежнее, поскольку он обрабатывает имена файлов, имеющих специальные символы, как «пространство» или «перевод строки»

Поэтому он также более сложный

find . -type f -printf '%11s %P\0' | 
    LC_ALL=C sort -z | 
    uniq -Dzw11 | 
    while IFS= read -r -d '' line 
    do 
    md5sum "${line:12}" 
    done | 
    uniq -w32 --all-repeated=separate | 
    tee duplicated.log 

Некоторые объяснения

# Print file size/md5sum/name in one line (size aligned in 11 characters) 
find . -printf '%11s ' -exec md5sum '{}' ';' 

# Print duplicated lines considering the the first 44 characters only 
# 44 characters = size (11 characters) + one space + md5sum (32 characters) 
uniq -w44 --all-repeated=separate 

# Print size and path/filename terminated by a null character 
find . -printf '%11s %P\0' 

# Sort lines separated by a null character (-z) instead of a newline character 
# based on native byte value (LC_ALL=C) instead of locals 
LC_ALL=C sort -z 

# Read lines separated by null character 
IFS= read -r -d '' line 

# Skip the first 12 characters (size and space) 
# in order to obtain the rest: path/filename 
"${line:12}" 
+0

это большое спасибо – slev

+0

Добро пожаловать ;-) Это также помогает мне найти мои файлы дубликатов :-D. Благодаря вашему вопросу, я улучшил свой дубликат поиска файлов. Большое вам спасибо => +1 за вас ;-) – olibre