Intereting Posts
Как записывать данные по одному из файлов tmp в конечный выходной файл, используя для цикла? как войти с помощью ssh с паролем? Сохранить количество строк, выводимых в переменную в сценарии оболочки, не потребляя выход Многократные скрининг в гольф Как установить машинное шифрование, чтобы разрешить только один компьютер для дешифрования данных X.org: два «экрана» на одном «устройстве» Передача переменной в скрипт bash, который использует «EOF» и рассматривает переменную буква включение ECMP в Linux В чем проблема с терминалами и цветами? Что такое kdeconnectd и как навсегда запретить его в брандмауэре? Ошибка при попытке восстановить RPM Переименование файлов и каталогов Рекурсивно использование переименования / поиска Возможно ли, чтобы sudo считывал пароль из gnome-keyring или аналогичного Многие аудиоустройства с одинаковым именем: как их использовать в asound.conf? Полностью отключить / деактивировать USB в Ubuntu 10.04

Поиск файлов с тем же именем, но с другим контентом?

Я хочу создать список файлов, которые имеют:

  • То же имя
  • Разный контент

в каталоге (включая все каталоги и содержимое для детей).

Как сделать? Бэш, перл, все в порядке.

Таким образом, два файла с тем же именем и одним и тем же содержимым не должны отображаться.

Обновление: исправлена ​​опечатка в скрипте: изменена print $NF для print $3 ; также прибрал вещи и добавил некоторые комментарии.

Предполагая, что имена файлов не содержат \n , следующее распечатывает отсортированный список, который разбивается (как в разделах : разрывы управления секциями ) на уникальное file name , уникальный md5sum и показывает соответствующую группу путей к файлам.

 #!/bin/bash # Choose which script to use for the final awk step out_script=out_all # Print all duplicated file names, even when md5sum is the same out_all='{ if( p1 != $1 ) { print nl $1; print I $2 } else if( p2 != $2 ) { print I $2 } print II $3; p1=$1; p2=$2; nl="\n" } END { printf nl}' # Print only duplicated file names which have multiple md5sums. out_only='{ if( p1 != $1 ) { if( multi ) { print pend } multi=0; pend=$1 "\n" I $2 "\n" } else if( p2 != $2 ) { multi++; pend=pend I $2 "\n" } pend=pend II $3 "\n"; p1=$1; p2=$2 } END { if( multi ) print pend }' # The main pipeline find "${1:-.}" -type f -name '*' | # awk for duplicate names awk -F/ '{ if( name[$NF] ) { dname[$NF]++ } name[$NF]=name[$NF] $0 "\n" } END { for( d in dname ) { printf name[d] } }' | # standard md5sum output xargs -d'\n' md5sum | # " "==text, "*"==binary sed 's/ [ *]/\x00/' | # prefix with file name awk -F/ '{ print $3 "\x00" $0 }' | # sort by name. md5sum, path sort | # awk to print result awk -F"\x00" -v"I= " "${!out_script}" 

Вывод, показывающий только имена файлов с несколькими md5 s

 afile.html 53232474d80cf50b606069a821374a0a ./test/afile.html ./test/dir.svn/afile.html 6b1b4b5b7aa12cdbcc72a16215990417 ./test/dir.svn/dir.show/afile.html 

Вывод, показывающий все файлы с тем же именем.

 afile.html 53232474d80cf50b606069a821374a0a ./test/afile.html ./test/dir.svn/afile.html 6b1b4b5b7aa12cdbcc72a16215990417 ./test/dir.svn/dir.show/afile.html fi le.html 53232474d80cf50b606069a821374a0a ./test/dir.svn/dir.show/fi le.html ./test/dir.svn/dir.svn/fi le.html file.html 53232474d80cf50b606069a821374a0a ./test/dir.show/dir.show/file.html ./test/dir.show/dir.svn/file.html file.svn 53232474d80cf50b606069a821374a0a ./test/dir.show/dir.show/file.svn ./test/dir.show/dir.svn/file.svn ./test/dir.svn/dir.show/file.svn ./test/dir.svn/dir.svn/file.svn file.txt 53232474d80cf50b606069a821374a0a ./test/dir.show/dir.show/file.txt ./test/dir.show/dir.svn/file.txt ./test/dir.svn/dir.show/file.txt ./test/dir.svn/dir.svn/file.txt 

Вот сценарий Perl. Запустите его в каталоге в верхней части дерева, которое вы хотите выполнить. Скрипт зависит от find и md5 , но последний может быть заменен на sha1 , sum или любую другую программу хеширования файлов, которая принимает входные данные на stdin и выводит хэш на stdout.

 use strict; my %files; my %nfiles; my $HASHER = 'md5'; sub print_array { for my $x (@_) { print "$x\n"; } } open FINDOUTPUT, "find . -type f -print|" or die "find"; while (defined (my $line = <FINDOUTPUT>)) { chomp $line; my @segments = split /\//, $line; my $shortname = pop @segments; push @{ $files{$shortname} }, $line; $nfiles{$shortname}++; } for my $shortname (keys %files) { if ($nfiles{$shortname} < 2) { print_array @{ $files{$shortname} }; next; } my %nhashes; my %revhashes; for my $file (@{ $files{$shortname} }) { my $hash = `$HASHER < $file`; $revhashes{$hash} = $file; $nhashes{$hash}++; } for my $hash (keys %nhashes) { if ($nhashes{$hash} < 2) { my $file = $revhashes{$hash}; print "$file\n"; } } } 

finddup этот инструмент также может помочь вам в перечислении файлов с одинаковыми именами или контентом.

Для тех, кто хочет видеть только список имен файлов, вот соответствующая часть ответа Peter.O :

 find "${1:-.}" -type f -name '*' | awk -F/ '{ if( name[$NF] ) { dname[$NF]++ } name[$NF]=name[$NF] $0 "\n" } END { for( d in dname ) { printf name[d] "\n" } 

Мне не нужны md5sums, потому что я использую fslint-gui перед скриптом, чтобы очистить все дубликаты.