Bash – Assignment to variables

bashcommand-substitutionquotingshell

I was trying to devise a solution to a different question asked on the site and came across this curious issue. Here is the set of commands that I issued:

$ foo=82a9948422
$ echo $foo
82a9948422
$ echo $foo | sed 's/./&\
/g' | sort | uniq -c | sort -n -r | head -1 | awk '{print $1}'
3
$ count=`echo $foo | sed 's/./&\
/g' | sort | uniq -c | sort -n -r | head -1 | awk '{print $1}'`
$ echo $count
1
$

Notice how the number of unique characters in the variable is 3 but when I assign it to a variable, it reports the count as 1. I'm puzzled. Can someone explain the discrepancy please?

Best Answer

Don't use backticks for command substitutions: the expansion rules are tricky and not completely consistent across shells. Use $(…) instead; it has exactly the same meaning, but an intuitive and portable syntax. You don't need to use any special quoting; the matching close parenthesis determines the end of the command and that's it. In the rare case when the command starts with an opening parenthesis, put a space to avoid confusion with arithmetic expansion (e.g.. variable=$( (foo; bar) || qux )).

count=$(echo $foo | sed 's/./&\
/g' | sort | uniq -c | sort -n -r | head -1 | awk '{print $1}')

or

count=$(echo $foo | sed 's/./&\n/g' | sort | uniq -c | sort -n -r | awk 'NR==1 {print $1}')
Related Question