3

I'm using this command to recursively generate a SHA-512 hash for each file in a directory hierarchy:

find . -type f -exec openssl sha512 {} \;

I'd like to sort the files in lexicographical order before generating the hashes.

I can use sort like this:

find . -type f | sort

but I'm not sure how to then pipe the sorted file list into openssl. I tried this:

find . -type f | sort | openssl sha512

but this generates a single hash of the entire output of sort, whereas I want a hash for each individual file.

find in some versions of bash includes an -s option ("Cause find to traverse the file hierarchies in lexicographical order"), but this isn't available in my version of find.

Many thanks in advance for your help!

5

You can use xargs to get what you want.

find . -type f -print0 | sort -z | xargs -0 -n1 openssl sha512

The -n1 option tells xargs to only allow one argument to be given to the openssl command. The -print0, -z and -0 options prevent the pipeline from breaking if there are "problem" characters (like an embedded newline) in the filenames.

  • Many thanks, that works perfectly! I haven't used xargs before, but I can see it's very useful for situations like this. It's great to learn that find, sort and xargs all have support for null-terminated items, so they can all be combined in a single pipeline like this! – TachyonVortex Nov 25 '12 at 16:18
1

Pipe it to xargs -L 1 openssl sha512, like this:

find . -type f | sort | xargs -L 1 openssl sha512

xargs takes outputs and runs it as the command line of the program, the "-L 1" limits it to one line per execution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.