Cut command fields

awkcommand-substitutioncutgrepuniq

I noticed these two different fields behaviors using cut command:

bash:~$ var=`cat /proc/cpuinfo | grep 'model name' | uniq | cut -d ' ' -f 3,4,5,6,7,8 `  
echo $var

outputs

Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz  

and:

bash:~$ echo `cat /proc/cpuinfo | grep 'model name' | uniq` | cut -d ' ' -f 3,4,5,6,7,8

outputs

: Intel(R) Core(TM) i7-3632QM CPU @  

fields numbers are the same but different outputs. Why?

Best Answer

It is because the unquoted `` backquote command substitution has removed an extra space between the model name and the : characters. Refer to the outputs without the grep to see the difference for yourself

echo `cat /proc/cpuinfo | grep 'model name' | uniq`
model name : Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz

and with

cat /proc/cpuinfo | grep 'model name' | uniq
model name  : Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz
#         ^^ - 2 spaces rather than one

As a result the cut sees different fields from number 3 onwards in both the cases. This can be fixed if you avoid using backticks and use $(..) with a proper quoted substitution

echo "$(cat /proc/cpuinfo | grep 'model name' | uniq)" | cut -d ' ' -f 3,4,5,6,7,8

But that said, using cat/grep etc sequentially can be avoided and a single awk can be used in-place of it

awk -F: '$1 ~ "model name" { print $2 }' /proc/cpuinfo

Or even more exact, if a single leading space in the above result is worrisome, remove it using sub

awk -F: '$1 ~ "model name" { sub(/^[[:space:]]/ ,"" , $2); print $2 }' /proc/cpuinfo

Or if you have GNU variant of grep which has PCRE regex enabled, which you can use as

grep -oP 'model name(\s+):(\s+)\K(.+)' /proc/cpuinfo
Related Question