Linux piping find и md5sum не отправляют вывод
Пытаясь зациклить каждый файл, выполнить вырезку, извлечь первые 4 символа MD5.
Вот что я получил так далеко:
find . -name *.jpg | cut -f4 -d/ | cut -f1 -d. | md5sum | head -c 4
Проблема в том, что я не вижу больше вывода на данный момент. Как я могу отправить вывод на md5sum
и продолжить отправку результата?
3 ответа
md5sum читает все от стандартного ввода до конца файла (eof) и выводит md5 сумму полного файла. Вы должны разделить ввод на строки и запустить md5sum для каждой строки, например, с помощью while read var
цикл:
find . -name *.jpg | cut -f4 -d/ | cut -f1 -d. |
while read -r a;
do echo -n $a| md5sum | head -c 4;
done
read
встроенная команда bash прочитает одну строку из ввода в переменную оболочки $a
; while
цикл будет запускать тело цикла (команды между do
а также done
) для каждого возврата из чтения, и $a будет текущей строкой. -r опция read - не конвертировать обратную косую черту; Опция -n команды echo не добавляет новую строку (если вы хотите новую строку, удалите опцию -n из echo).
Это будет медленным для тысяч файлов и более, так как для каждого файла в цикле есть несколько forks/execs. Быстрее будут некоторые сценарии с использованием perl или python или nodejs или любого другого языка сценариев со встроенными хэш-вычислениями md5 (или с некоторой библиотекой).
Вы можете делать то, что пытаетесь сделать, с помощью короткого "вспомогательного" скрипта, из которого вы вызываете find
, Например, вы можете создать короткий скрипт, чтобы найти basename
каждого файла, переданного в качестве аргумента, удалите '.jpg'
расширение, а затем предоставить оставшееся имя без расширения в качестве входных данных для md5sum
на stdin
чтобы получить md5sum
самого названия. Назовите сценарий как хотите, скажем namemd5.sh
, Пример:
#!/bin/bash
[ -z "$1" ] && exit 1 ## validate single argument
fname=$(basename "$1") ## get the filename alone
fname="${fname%.jpg}" ## remove .jpg extension
fnsum=$(md5sum - <<<"$fname") ## get md5sum of name w/o .jpg
fnsum=${fnsum%% *} ## remove trailing ' -'
echo "$fnsum - $fname" ## output md5sum - name
## (remove ' - $fname' for md5sum alone)
(примечание: имя предоставляется как часть выходных данных в качестве примера, удалите, если хотите md5sum
один, как показано в комментарии выше)
Файлы примеров
$ find /home/david/img/wp/ -type f -name "*.jpg"
/home/david/img/wp/hacker_manifesto_1200x900.jpg
/home/david/img/wp/hacker_manifesto_by_otalicus.jpg
/home/david/img/wp/reflections-triple-1920x1200.jpg
/home/david/img/wp/hacker_wallpaper_1600x900.jpg
/home/david/img/wp/Zen.jpg
/home/david/img/wp/hacker_wallpaper_by_vanilla23-dot254.jpg
/home/david/img/wp/hacker_manifesto_1600x900.jpg
Пример использования / Вывод
$ find /home/david/img/wp/ -type f -name "*.jpg" -exec ./namemd5.sh '{}' \;
0f7d2aac158eb9f7842215e14ff6573c - hacker_manifesto_1200x900
604bc695a0bb70b8db0352267caf226f - hacker_manifesto_by_otalicus
5decea0e306f185bf988ac9934ec0e2c - reflections-triple-1920x1200
82bd8e1ad3df588eb0e0848c5f764812 - hacker_wallpaper_1600x900
0f4daba431a22c03f28977f087e4c695 - Zen
0c55cd3ebd2a847e10c20d86e80e6ceb - hacker_wallpaper_by_vanilla23-dot254
e5c1da0c2db3827d2bf81c306633cc56 - hacker_manifesto_1600x900
Вы также можете вызвать скрипт с -execdir
версия внутри find
а также, например
$ find /home/david/img/wp/ -type f -name "*.jpg" -execdir \
/full/path/to/namemd5.sh '{}' \;
(примечание: использование /full/path
на ваш вспомогательный скрипт выше)
Как найти все файлы.jpg, затем выполнить md5sum, а затем вырезать первые 4 символа:
find . -name '*.jpg' -exec md5sum {} \; | cut -b 1-4