Отримати хеш-значення можна лише за допомогою md5sum (без імені файлу)


176

Я використовую md5sum для створення хеш-значення для файлу. Але мені потрібно лише отримати значення хеша, а не ім'я файлу.

md5=`md5sum ${my_iso_file}`
echo ${md5}

3abb17b66815bc7946cefe727737d295 ./iso/somefile.iso

Як я можу "зняти" ім'я файлу і залишитися лише значенням?


27
Дуже дивно, що це не варіант для md5sum.
Шрідхар Сарнобат

11
Домовились! Чому це не варіант? Чи може магістр GNU пролити трохи світла?
rinogo

Чому вам потрібно мати прапор "тільки хеш", коли ви можете обрізати результат деяким регулярним виразом? (Я саркастичний)
Magnetic_dud

Відповіді:


163

Ну інший спосіб :)

md5=`md5sum ${my_iso_file} | awk '{ print $1 }'`

7
Або md5=`md5sum < ${my_iso_file}` однак це все ще виводить "-" наприкінці. Але для порівнянь цього має бути достатньо.
Крістоф Де Троєр

Неправильно він дає наступний вихід на Mac MD5 (/Users/hello.txt) = 24811012be8faa36c8f487bbaaadeb71і ваш код повертається MD5.
альпер

Ви можете розпочати роботу -, додавши | awk '{print $1}'кінець свого коду => md5sum < ${my_iso_file} | awk '{print $1}'@ChristopheDeTroyer
alper

191

Просте призначення масиву працює ... Зверніть увагу, що перший елемент bashмасиву може бути адресований просто індексом nameбез [0]індексу, тобто $md5містить лише 32 символи md5sum.

md5=($(md5sum file))
echo $md5
# 53c8fdfcbb60cf8e1a1ee90601cc8fe2

Дивовижно. Лише одне запитання, я знаю, що це позначено тегами bash, але чи можете ви сказати мені, чи масив є лише функцією bash або якимсь стандартним оболонки?
jyz

перший рядок не працює в розділі do циклу для циклу ... як новобранець Баша, я ще не знаю, чому
Енді

@Andy: Якщо ви спробуєте цей рядок коду (в терміналі або в скрипті): echo>file; for i in file; do md5=($(md5sum file)); echo $md5; done- Це повинно вивести68b329da9893e34099c7d8ad5cb9c940
Peter.O

1
Як echo ($(echo -n foo | md5sum))це не працює? Помилки bash: syntax error near unexpected token $(echo -n foo | md5sum)'
lkraav

2
@lkraav: Команда echo -n foo | md5sum виводить два слова оболонки до stdout : acbd18db4cc2f85cedef654fccc4a4d8і -( -вказує джерело як stdin ). - Ви повинні сказати Баш , щоб захопити ці слова в рядок, використовуючи Підстановку команд : $( command ). - (Дужки )створюють масив bash з 2 елементами. Однак ви повинні призначити цю конструкцію масиву ( … )імені змінної; отже, використовуючи md5 як ім'я масиву: md5=($(echo -n foo | md5sum)). Ви не призначили масив імені змінної
Peter.O

57

Ви можете використовувати cutдля розділення рядка на пробіли та повернення лише першого такого поля:

md5=$(md5sum "$my_iso_file" | cut -d ' ' -f 1)

18
Абоcut -c 1-32
Czarek Tomczak

7
@CzarekTomczak Щоправда, але просто використовуючи метод цієї відповіді, ви можете повторно використовувати його за допомогою різних алгоритмів хешування, просто змінивши саму команду. md5sum-> sha256sumне пам’ятаючи, яку кількість символів потрібно «вирізати».
Девід Табернеро М.


14
md5="$(md5sum "${my_iso_file}")"
md5="${md5%% *}" # remove the first space and everything after it
echo "${md5}"

Приємно. Одна примітка - у першому рядку вам не потрібні цитати $()(хоча вони не приносять шкоди), але, безумовно, потрібні ${}.
Роман Чепляка

1
@ Роман: Так, я, як правило, цитую будь-яке розширення (якщо немає причини цього не робити) - це простіше, ніж відслідковувати випадки, коли безпечно пропустити цитати. (Хоча в цьому випадку я залишив їх фактичним іменем файлу ... очікуйте на редагування.)
Гордон Девіссон,

5

Односторонній:

set -- $(md5sum $file)
md5=$1

Інший спосіб:

md5=$(md5sum $file | while read sum file; do echo $sum; done)

Інший спосіб:

md5=$(set -- $(md5sum $file); echo $1)

(Не намагайтеся це робити із зворотними кліщами, якщо ви не дуже сміливі та дуже хороші з накидами.)

Перевага цих рішень перед іншими рішеннями полягає в тому, що вони лише викликають md5sumі оболонку, а не інші програми, такі якawk або sed. Чи це насправді має значення, то це окреме питання; вам, мабуть, буде важко помітити різницю.


4

Ще один спосіб:

md5sum filename |cut -f 1 -d " "

Вирізання розділить лінію на кожен пробіл і поверне лише перше поле.



2

Якщо вам потрібно роздрукувати його і не потрібен новий рядок, ви можете використовувати:

printf $(md5sum filename)


0

md5sumставить зворотну косу рису перед хешем, якщо в імені файлу є зворотна косою рисою. Перші 32 символи або що-небудь перед першим пробілом може бути не належним хешем. Це не відбудеться при використанні стандартного вводу (ім'я файлу буде просто -), тому відповідь pixelbeat спрацює, але багато інших потребуватимуть додавання чогось подібного | tail -c 32.


0

Що ж, у мене була та сама проблема сьогодні, але намагаюся отримати файл md5 хеш при виконанні findкоманди. Я отримав найбільш проголосоване запитання і вклав його у функцію, закликану md5запустити команду пошуку Місією для мене було обчислити хеш для всіх файлів у папці та вивести його як hash:filename.

md5() { md5sum $1 | awk '{ printf "%s",$1 }'; }
export -f md5
find -type f -exec bash -c 'md5 "$0"' {} \; -exec echo -n ':' \; -print

Отже, я отримав би фрагменти звідси, а також від find -exec функції оболонки?


0

Для повноти спосіб з sed використовуючи регулярний вираз і групу захоплення:

md5=$(md5sum "${my_iso_file}" | sed -r 's:\\*([^ ]*).*:\1:')

Регулярний вираз охоплює все в групі, поки не буде досягнуто пробілу. Для роботи групи захоплення вам потрібно захопити все в sed. (Докладніше про групи sed і caputer тут: https://stackoverflow.com/a/2778096/10926293 )
Як роздільник в sed я використовую колонки, оскільки вони не дійсні в файлових шляхах, і мені не потрібно уникати розрізаних в filepath.



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.