2

I'm using the command below to generate a list of files and their m5sum. The problem is that some of the files or folders have spaces in the name. How would I handle those?

find -type f -name \* | xargs md5sum
knocte
  • 16,941
  • 11
  • 79
  • 125
iheartcpp
  • 371
  • 1
  • 5
  • 14

3 Answers3

5

Try:

find . -type f -exec md5sum {} +

With this command, find will run md5sum on the files that it finds.

MacOS: According to the MacOS find man page, find on a Mac does not support the + option. Instead, the somewhat less efficient (see note 3 below) form is required:

find . -type f -exec md5sum {} \;

Notes:

  1. -name \* tells find to search for all files. Since this is the default, it is not necessary to specify it.

  2. It is common for modern file names to have spaces in their names. In fact, they can even have newlines in their names. Consequently, xargs is generally not safe to use unless one uses the -0 or --null options to tell it to use NUL-separated input. This can be combined with find's -print0 which tells find to generate NUL-separated output. Since, however, -exec can do most things that xargs can do and is safe to use with difficult file names, the -exec form is usually preferred.

  3. If we had used the form -exec md5sum {} \;, then find would run md5sum once for each file found. The form -exec md5sum {} +, by contrast, will place many file names on the command line. This greatly reduces the number of processes that have to be started.

Example

Sample output from the above command looks like:

$ find . -type f -exec md5sum {} +
e75632e8a11db7513c2a9f25cb6c9627  ./file1
004dedba9b67f3a93924db548fd4d6ef  ./file2
48645402a2cf6ada3548ad69d8d906db  ./dir1/file1
6a182d8fe659c067897be7fde72903ea  ./dir1/file2
John1024
  • 109,961
  • 14
  • 137
  • 171
  • doesn't work on macOS, while @Adam's answer (below) with the pipe (|) works – knocte Oct 21 '21 at 09:56
  • @knocte Thanks for that info. It is not unusual for Mac utilities to be slightly different. After looking up info on [MacOS `find`](https://ss64.com/osx/find.html), I just added to the answer a command that appears it should work on a Mac. Please give it a try and let me know if it works. – John1024 Oct 22 '21 at 19:18
2

find can make up the xargs directly and avoid use of the | command by using the -exec flag. In this syntax you use {} to represent that name of the found file and + indicates the end of the command.

Therefore you should be able to run this command to get the result you want:

find -type f -exec md5sum "{}" +

If you really want to use pipe, then you need to tell find to delimit the responses with a null and xargs to expect null delimited arguments like this:

find -type f -print0 |xargs -0 md5sum
Adam Bumpus
  • 46
  • 1
  • 3
  • note for the macOS users out there, the xargs equivalent is `find . -type f -print0 | xargs -0 md5` – knocte Dec 30 '22 at 05:35
0

The answers above were not really working for me, so I had to use this:

find . -type f -name "*.*" | xargs -t -I {} md5sum {}

(The -t flag will make print each command for each file.)

knocte
  • 16,941
  • 11
  • 79
  • 125