4

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!

2 Answers 2

7

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.

1
  • 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! Commented Nov 25, 2012 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.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.