Кажется, я нашел причину зависания ядра. Последовательный драйвер atmel _отключает передатчик UART, когда init закрывает консольное устройство (/dev/console ). Затем следующий printk из ядра зависает, ожидая, пока THR не опустеет. Эта ошибка была исправлена в ветке upstream 4.4 -at91 (https://github.com/linux4sam/linux-at91/commit/0a1757cfa5ba3b46f6ee7a74ddb7a5c0bd5d7c2f)
.
Немного расширив решение @Isaac....
Предполагая синтаксис bash
и учитывая:
$ find test -type f
test/AA
test/A
test/C
test/CC
test/B
test/D
где файлы A и AA идентичны, как C и CC;
Это более эффективный конвейер команд.:
$ find test -maxdepth 1 -type f -exec bash -c "md5sum < {}" \; |
sort -k1,1 |
uniq --count
2 102f2ac1c3266e03728476a790bd9c11 -
1 4c33d7f68620b7b137c0ca3385cb6597 -
1 88178a003e2305475e754a7ec21d137d -
2 c7a739d5538cf472c8e87310922fc86c -
Оставшаяся проблема заключается в том, что хэши md5 не говорят вам, какие файлы являются A, B, C или D. Это можно решить, хотя это немного неудобно.
Во-первых, переместите свои файлы в подкаталог или переместите свой PWD на один каталог выше, если это более удобно. В моем примере я работаю в .
, а файлы находятся в test/
.
Я предлагаю вам определить по одному файлу каждого из четырех типов и скопировать их в файл A, B, C и D (и далее, если вам нужно, вплоть до Z):
$ cp -p test/file1002./A
...
$ cp -p test/file93002./N
и т. д. Теперь мы можем построить хэш-таблицу, которая определяет хэши md5 каждого уникального выходного файла A -Z:
$ for file in [A-Z]; do
printf "s/%s/%s/\n" "$(md5sum < $file )" "$file";
done
s/102f2ac1c3266e03728476a790bd9c11 -/A/
s/4c33d7f68620b7b137c0ca3385cb6597 -/B/
s/c7a739d5538cf472c8e87310922fc86c -/C/
s/88178a003e2305475e754a7ec21d137d -/D/
Обратите внимание, что хеш-таблица имеет синтаксис sed
. Вот почему:
Запустим тот же конвейер find... md5sum
выше:
$ find test -maxdepth 1 -type f -exec bash -c "md5sum < {}" \; |
sort -k1,1 |
uniq --count
... и передать его через процесс sed
, который использует приведенную выше хеш-таблицу для замены хеш-значений именами файлов-прототипов. Команда sed
сама по себе будет:
sed -f <(
for file in [A-Z]; do
printf "s/%s/%s/\n" "$(md5sum < "$file")" "$file";
done
)
Чтобы соединить все вместе:
$ find test -maxdepth 1 -type f -exec bash -c "md5sum < {}" \; |
sort -k1,1 |
uniq --count |
sed -f <(
for file in [A-Z]; do
printf "s/%s/%s/\n" "$(md5sum < "$file")" "$file";
done
)
2 A
1 B
1 D
2 C
Если вы видите такой вывод:
2 A
1 B
1 5efa8621f70e1cad6aba9f8f4246b383 -
1 D
2 C
Это означает, что в test/
есть файл, значение MD5 которого не соответствует вашим файлам A -D. Другими словами, где-то существует формат выходного файла E
. Как только вы найдете его (md5sum test/* | grep 5efa8621f70e1cad6aba9f8f4246b383
), вы можете скопировать его в E и заново -запустить :
$ cp -p test/file09876./E
$ find test -maxdepth 1 -type f -exec bash -c "md5sum < {}" \; |
sort -k1,1 |
uniq --count |
sed -f <(
for file in [A-Z]; do
printf "s/%s/%s/\n" "$(md5sum < "$file")" "$file";
done
)
2 A
1 B
1 E
1 D
2 C
Используйте хеш-карту для сбора всех уникальных файлов. Хэш зависит от содержимого, поэтому только файлы с уникальным содержимым получают запись в хеш-карте.
declare -A unique_files
for file in *; do
unique_files["$(md5sum "$file" | cut -d ' ' -f 1)"]="$file"
done
echo "${unique_files[@]}"
Для этого также можно использовать sort
и uniq
. В папке, где находятся файлы, введите:
find. -type f | awk '{ print "tr \\\\n @ < " $0 "; echo "}' | sh | sort | uniq --count
(Замените uniq --count
на uniq -c
, если не используется uniq
из GNU coreutils.)
Это должно дать вам результаты сразу. Для простоты и скорости (избегая хэшей )мы переводим новые строки в@
--это может быть любой отдельный символ, не являющийся частью исходного файла.
(Это предполагает, что файлы в подпапках -, если они существуют, должны быть включены. Другое предположение состоит в том, что в файле нет символа @
. Если нет, пожалуйста, прокомментируйте, и я соответствующим образом изменю команду.)
Я большой поклонник GNUdatamash
(https://www.gnu.org/software/datamash/). Вот пример вывода смоделированного набора файлов, который я создал и запустил эту команду на:
$ md5sum * | datamash -W -s -g 1 count 2 -f
5591dadf0051bee654ea41d962bc1af0 junk1 27
9c08c31b951a1a1e0c3a38effaca5863 junk2 17
f1e5cbfade7063a0c4fa5083fd36bf1a junk3 7
Есть 27 файлов с хешем 5591..., и один из них "junk1". (Точно так же 17 файлов, которые совпадают с "junk2", и 7 для "junk3" ).
-W
говорит использовать пробелы в качестве разделителя полей. -s -g 1
говорит о сортировке и группировке по полю 1 (, которое является хешем ). count
могло быть либо полем 1, либо полем 2, не имеет значения.
-f
говорит "печатать всю строку ввода". У этого есть особенность: когда вы печатаете агрегированные результаты, он печатает только полную строку для первой строки в каждой найденной группе. В данном случае это работает нормально, поскольку дает нам одно из имен файлов, участвующих в каждом наборе дубликатов -, а не все.