# sysctl -n hw.model



## Niatross (Jan 7, 2013)

I type the *sysctl -n hw.model* command to retrieve the following information about my processor:


```
Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz
```

I want to extract the information (above) into three separate parts (using three separate *sysctl -n hw.model* commands).

Example:

```
Manufacturer: Intel
Processor Number: i7 870
Clock Speed: 2.93GHz
```

How would I use the sysctl(8) command to pull the word "Intel"?
How would I use the sysctl(8) command to pull the word "i7" and the value "870"?
How would I use the sysctl(8) command to pull the value "2.93GHz"?

PS: Color codes are only used to display the information I want to pull together.


----------



## SirDice (Jan 7, 2013)

And this is where things like awk(1), sed(1), perl(1), python(1) and ruby(1) become useful.


----------



## Niatross (Jan 7, 2013)

SirDice said:
			
		

> And this is where things like awk(1), sed(1), perl(1), python(1) and ruby(1) become useful.



I understand it takes these commands, but can you help this dummy out a little with the syntax?


----------



## wblock@ (Jan 7, 2013)

You need to develop some rules for where information is located in the string.

The first part of the string, possibly multiple words, is the manufacturer.
After the manufacturer and up to the "@ " is the processor model number.  These are not consistently worded.
The part of the string following "@ " is the frequency.

Then pick a tool that can strip information from a string.  awk(1) is less horrible than sed(1).  Perl is better than either.


----------



## Niatross (Jan 7, 2013)

wblock@ said:
			
		

> You need to develop some rules for where information is located in the string.
> 
> The first part of the string, possibly multiple words, is the manufacturer.
> After the manufacturer and up to the "@ " is the processor model number.  These are not consistently worded.
> ...



So would the following command be good to pull the value "2.93GHz"?


```
sysctl -n hw.model | awk -F '@ ' '{print $2}'
```

It does the trick, but is this command a hokey way of doing it? Should I do it another way?


----------



## wblock@ (Jan 7, 2013)

It works in this case.  I just saw that some AMD processors don't have an "@" in the string, the last word is the frequency, like "3200+".

In all cases, the first word is probably the manufacturer, and the last word the rated frequency.  Tested:

```
#!/bin/sh
CPUSTR=$( sysctl -n hw.model )
MFR=$( echo ${CPUSTR} | awk '{print $1}' )
CPUID=$( echo ${CPUSTR} | awk '{for (i=2; i<NF; ++i) {printf "%s ", $i} }')
SPEED=$( echo ${CPUSTR} | awk '{print $NF}' )
echo "Manufacturer: ${MFR}"
echo "      CPU ID: ${CPUID}"
echo "       Speed: ${SPEED}"
```


----------



## Niatross (Jan 7, 2013)

wblock@ said:
			
		

> It works in this case.  I just saw that some AMD processors don't have an "@" in the string, the last word is the frequency, like "3200+".
> 
> In all cases, the first word is probably the manufacturer, and the last word the rated frequency.  Tested:
> 
> ...




I'm getting this:


```
./test.sh
Manufacturer: Intel(R)
      CPU ID: Core(TM) i7 CPU 870 @ 
       Speed: 2.93GHz
```

Is there a way that the second line can read:


```
CPU ID: i7-870
```

I don't have AMD so I'm ignorant on what the *sysctl -n hw.model* command would display on AMD platforms.

Like you said, AMD returns a completely different answer when using the *sysctl -n hw.model* command. It most likely wouldn't make sense to create a script that can pull the "i7-870" on a Intel platform (...because if I used the same script on an AMD platform, it would bomb). It gets difficult pulling data from a string when we don't even know what value will be returned using the *sysctl -n hw.model*  command on every Intel and AMD platform out there.

Bummer.


----------



## wblock@ (Jan 7, 2013)

If it were easy, anyone could do it. 

You'll have to parse out the CPU type and model number, and that will be tricky.  For Intel, it may be that the last word before the "@" is always the model number, but that's probably not something that can be counted on.  Count the words between the manufacturer and the model number as the CPU ID, but only if it is Intel...  Resorting to special-case tests might be the only way:
(in Perl)

```
return "i7-870" if /i7 CPU 870/;
return "i5-2500K" if /i5-2500K CPU/;
```

On AMD, the manufacturer is "AMD" and it says "Processor" rather than "CPU".

If it has to be general-case and handle many different processors, look for what others have done.  The source to HDT might help, or sysutils/dmidecode.


----------



## Niatross (Jan 7, 2013)

wblock@ said:
			
		

> It works in this case.  I just saw that some AMD processors don't have an "@" in the string, the last word is the frequency, like "3200+".
> 
> In all cases, the first word is probably the manufacturer, and the last word the rated frequency.  Tested:
> 
> ...



So the following prints the last field of an input line:


```
$NF
```

Interesting. Thanks for teaching me this!  Learning sloooowly but surely. One day I'll get it.


----------



## wblock@ (Jan 7, 2013)

NF=Number of Fields.  So if you use NF as an index, it gives the last field.


----------



## DutchDaemon (Jan 7, 2013)

Also try $(NF-1), $(NF-2), ..


----------



## phoenix (Jan 8, 2013)

Niatross said:
			
		

> I'm getting this:
> 
> 
> ```
> ...



Which is correct. The CPU model name includes Core. It's not just "i7".

However, if you are really stuck on not having it there, pipe that variable into awk, using ) as the separator, and print $2.


----------



## Wiedmann (Jan 8, 2013)

wblock@ said:
			
		

> You'll have to parse out the CPU type and model number, and that will be tricky.  For Intel, it may be that the last word before the "@" is always the model number,* but that's probably not something that can be counted on.*


For example I have:

```
> sysctl -n hw.model
Intel(R) Pentium(R) M processor 1.60GHz
```


----------

