Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question
2  
This has to do with how backticks handle whitespace in the output of the commands inside them. I got the correct result (3) by using the $() construct instead. The backtick form fails during the sorting step (the characters are never split in the first place). As to why this is so, you'll have to wait for someone more knowledgeable to answer. –  Joseph R. Feb 22 at 17:57
2  
Double your backslashes inside `...` or use $(...) –  Stéphane Chazelas Feb 22 at 18:14
1  
Both the solutions worked. Thanks. –  unxnut Feb 22 at 18:56

1 Answer 1

up vote 2 down vote accepted

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}')
share|improve this answer
    
Seconded... and another advantage of using command substitution parens() is that they can be nested arbitrarily. –  Stabledog Feb 23 at 2:00

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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