Help with finding a substring from the output of a variable

howie_isaacks
Valued Contributor II

I'm not actually having a problem with something but I was playing around with being able to find a substring from the output of a variable. I can't get this to give me the expected result.

#!/bin/zsh

proc=$(system_profiler SPHardwareDataType | grep "Chip:" | /usr/bin/awk '{print $2,$3,$4}')
echo $proc

if [ "$proc" = *"M2"* ]; then
	echo "M2 processor installed"
else
	echo "unknown"
fi

The correct result should be "M2 processor installed". I get "unknown".  I looked up how to do this and found this site:

https://linuxize.com/post/how-to-check-if-string-contains-substring-in-bash/

After reading that site I changed my conditional statement to match the syntax in the article.

#!/bin/zsh

proc=$(system_profiler SPHardwareDataType | grep "Chip:" | /usr/bin/awk '{print $2,$3,$4}')

echo "$proc"

if [[ "$proc" = *"M2"* ]]; then
  echo "M2 Processor installed"
else
  echo "unknown"
fi

This works. The only change I made was to use "[[ ]]" instead of "[ ]". I have written a lot of conditional statements using "[ ]" and they all work. I have also used "[[ ]]" and they work too. Why did this not work when I used "[ ]"? Knowing this will save me a lot of annoyance in the future. When I can't get a script to work, it's most often the case that I am using the wrong syntax. I'm not new to scripting but I am always happy to get tips and advice. 

1 ACCEPTED SOLUTION
5 REPLIES 5

Thanks! This looks very helpful. The Bash Reference Manual linked there has a lot of great info.

In addition to @thebrucecarter 's answer, I would recommend using the '-xml' option when using system_profiler so that you can extract the value without relying on output formatting. It's a bit more verbose, but should be more reliable over time.

❯ system_profiler -xml SPHardwareDataType | plutil -extract '0._items.0.chip_type' raw -
Apple M1 Max

OR

❯ system_profiler -xml SPHardwareDataType | xmllint -xpath '//key[text() = "_items"]/following-sibling::*[1]//key[text() = "chip_type"]/following-sibling::*[1]/text()' -
Apple M1 Max

 

howie_isaacks
Valued Contributor II

Thanks. The code I started the thread with was just used as an example of trying to find the right syntax to get what I needed. I like finding out new ways to get the outputs that I need so thanks for posting this.

pete_c
Contributor III

You might want to try:

/usr/sbin/sysctl -n machdep.cpu.brand_string

Faster than system_profiler as well.