0

I'm looking for a the simplest one-instruction solution to manipulate a computed string.
For example, removing the last two characters on a computed string: md5sum returns with ' -' at the end.

I can do it in two instructions:

$ a=$(echo 'ab'|md5sum); a=$(echo ${a:0:-2})
$ echo $a # (not required instruction)
daa8075d6ac5ff8d0c6d4650adb4ef29

How do I do it with one instruction, like the following?

$ a=${(echo 'ab'|md5sum):0:-2}
-bash: ${(echo 'ab'|md5sum):0:-2}: bad substitution

Thank you.

7
  • 1
    What is the point? The second assignment is totally within the shell (echo is a builtin). A real thing to do better is a="${a:0:-2}" instead of a=$(echo ${a:0:-2}). Commented Oct 18, 2023 at 5:28
  • Bash doesn't have nested parameter expansion, so you'll have to use something else. Maybe just read a _ < <(echo ... | md5sum)? But anyway, I agree with @KamilMaciorowski there's not much point to forcing this into one command. Commented Oct 18, 2023 at 5:30
  • 1
    in zsh, you could do a=${"$(echo 'abcxx')":0:-2}, but other shells don't support nested expansions like that. (There's some oddity there where it requires the quotes to treat the command substitution output as a single string instead something split to a list. Of course you could also utilize that with the output of md5sum.) Commented Oct 18, 2023 at 14:55
  • @ Kamil Maciorowski - thank you for the code without the echo. @ muru - thank you for the answer I was looking for, that Bash doesn't have nested parameter expansion. @ ilkkachu - thanks for suggesting zsh. I always want to learn the better dialect, but sadly, don't have the time!. @ Chris Davies - thanks for your efforts and explanation Commented Oct 19, 2023 at 5:35
  • echo 'ab' | md5sum will give you the hash of ab\n, not the hash of ab. You should probably be doing printf 'ab' | md5sum instead so a \n isn't being added to the md5sum input, depending on how you're using the resulting hash. Commented Oct 19, 2023 at 14:09

1 Answer 1

1

POSIXly you could use this:

a=$(echo 'ab' | md5sum)
a=${a%??}

Result in $a is daa8075d6ac5ff8d0c6d4650adb4ef29

You could omit the second assignment if you're just going to be using ${a%??}, but unless you're going to use it immediately I'd advise against this. (As coding style goes it would separate the two parts of generating the required value, and that in turn would create a fragile association that can make code maintenance more difficult.)

To do this in one assignment would be possible, but marginally less efficient:

a=$(echo 'ab' | md5sum | sed 's/..$//')

Be aware that in both cases, echo 'ab' will include the trailing newline in the MD5 checksum. You might want to use echo -n 'ab', or more portably printf '%s' 'ab'.

0

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.