25

Maybe it is a trivial question, but in the man page I didn't find something useful. I am using Ubuntu and bash.

The normal output for sha512sum testfile is

<hash_code> testfile 

How to suppress the filename output? I would like to obtain just

<hash_code> 
1
  • 3
    You need help from other tools, like sha512sum testfile | awk '{print $1}' Commented Feb 25, 2016 at 13:48

7 Answers 7

28

There isn't a way to suppress that, but since the SHA is always a single word without spaces you can do:

sha512sum testfile | cut -d " " -f 1 

or e.g.

< testfile sha512sum | sed 's/ -//' 
8
sha512sum testfile | awk '{print $1}' 
2

As mentioned by other answers: cut, awk, sed can be used to weed out the file name.

I'd like to add another solution to it without an external programs.

sum=$(sha512sum -- $file) sum=${sum%% *} 

%% is a posix parameter expansion which removes the suffix (greedily) that matches the pattern, in this case *. hence the filename would be removed leaving you with just the checksum.

1

Maybe just add an alias in your ~/.profile per the Anthon's way of cutting the first argument would help as a permanent solution,

sha() { sha512sum -- "$1" | cut -d " " -f 1 } 

To get it working, we obviously would need to run it once as, . .profile in ~.

Now putting only sha <file_name> would yield the way you wish it.

1
1

The answers given so far that post-process the output of sha512sum fail to take into account that for file paths that contain newline, carriage return or backslash characters, the output ends up with the checksum prefixed with a \ character:

$ sha512sum 'a\b' \cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e a\\b 

So, for arbitrary files, it should rather be:

sha512sum -- "$file" | LC_ALL=C sed 's/^\\//; s/ .*//' 

(LC_ALL=C in case $file contains byte sequences that can't be decoded as text in the user's locale).

That still doesn't work for file=- where sha512sum interprets that - as meaning stdin instead of the file called - in the current working directory.

Using:

sha512sum < "$file" | cut -d ' ' -f1 

Avoids all those issues.

Even better:

( set -o pipefail sha512sum | cut -d ' ' -f1 ) < "$file" 

Avoids running both sha512sum and cut if $file can't be opened for reading, and the pipefail option allows failure of sha512sum (such as death by signal or read error) to be reported in the overall exit status.

0

I also was frustrated by sha??sum stdout format, I used;

sha512sum | tr " " "\n" | head -n 1 
0

This was added a long time ago, but I feel I should warn you all that for every pipeline you add, you will be increasing process time.

If you are processing thousands of large files over a network, this sort of scripting will slow things down exponentially.

You are far better off writing a C++ binary that can output the data for you using a library such as Qt or libssl.

Otherwise you will want to let the shell handle the output instead. Use a flexible shell such as zsh for this:

mysum=${$(sha1sum $filename)[1]}

This will only grab the sum and not the filename (which could have been accessed with [2].

That said, you are far better off running shasum againt ALL the files you need verified, and save the bulk of the results in a single data chunk, then extract the sums in one go. In zsh you could do it like this:

sums=( ``sha1sum *(.)`` ) for sum filename in $sums { # each item is neatly tucked into $sum and $filename for your choosing! } 

This allowing you easily get at the shasum for each filename, and cuts the read time down considerably. The first *(.) zsh-ism is a regular glob that selects only regular file elements (not directories or symlinks). You can reverse this by specifying *(^.) to get directories and symlinks or *(/) to get just directories and not symbolic links at all.

If you are wondering if zsh is less efficient or has more overhead than bash, it really does not. I have replaced all my bash and sh scripts with zsh, and in many cases things run faster, especially since you can compile any zsh script into a binary using zcompile quite easily.

I have made this transition to zsh even on my potato devices (such as my very old 2-core laptop) with nothing but improvement.

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.