On OS X, system_profiler SPHardwareDataType outputs:

Hardware Overview:

  Model Name: MacBook Pro
  Total Number of Cores: 4
  L2 Cache (per Core): 256 KB
  L3 Cache: 8 MB
  Memory: 8 GB

I want to get the Memory value, trimmed of whitespaces.

This is what I had:

system_profiler SPHardwareDataType | grep --color=never -E '^ +Memory: ' | cut -d ':' -f 2

Not ok. It keeps the whitespace.

I switched to this:

system_profiler SPHardwareDataType | perl -ne 'if(/^ +Memory: (.*)$/){print $1;}'

and I'd like to ask:

  • Could this be made more concise in Perl?

The braces annoy me, often I type them wrong. Having to put the condition in () is also bothersome. The semicolon is bothersome.

  • Could this be made as concisely using more basic UNIX tools? (grep/sed/awk)?

Note: I do not use this line I like..

system_profiler SPHardwareDataType | sed -Ene 's/^ +Memory: (.*)$/\1/g p'

because extended regexes (-E are -r on some platforms? possible?) and fundamentally because, although I understand that sed works on lines, -n suppresses output unless I explicitly p print it, s//g is a normal regex substitute.. and that commands following a match are only executed on matching lines.. I am puzzled by the fact that s//g in reality is an action in itself.. so I would expect p to require a ; before it.. odd that you can both replace and use the match as a condition to execute the comand.. is that line correct at all?


Awk would make it most consise:

system_profiler SPHardwareDataType | awk  -F': ' '/Memory:/{print $2}'
  • Does not capture the unit of measure, in that case GB, which was desirable.. perhaps a capture "from field 2 to NF"? How would you write that? – Robottinosino Mar 29 '13 at 19:38
  • Not sure, so I simply edited the answer to use a proper -F parameter :) – Dennis Kaarsemaker Mar 29 '13 at 19:46
  • This is the best I have found anywhere. The -F to include both the colon and the space trims the rest of the line already, in one go. Very compact, exactly right.. LIKE! – Robottinosino Mar 29 '13 at 20:11

This is all you really need for the Perl one:

system_profiler SPHardwareDataType | perl -nle '/ry:\s*(.*)/ && print $1'

Some other choices:

  • system_profiler SPHardwareDataType | /bin/grep Me | gawk '{print $2,$3}'

    Using /bin/grep eliminates the need for --color=never. grep is defined as an alias to grep --color=auto in /etc/bash.bashrc (at least it is on most Linux distros and, I guess, on OSX).

  • system_profiler SPHardwareDataType | /bin/grep Me | /bin/egrep -o '[1-9]+.+'

    The -o causes grep toprint only the matched characters.

  • system_profiler SPHardwareDataType | tail -n 1 | cut -d ' ' -f 4,5

  • system_profiler SPHardwareDataType | tail -n 1 | sed 's/.*: //g'

system_profiler SPHardwareDataType | sed -n 's/^ *Memory: //p'

p here is a flag to the s command (like g), not the p command, and means print the pattern space if the substitution takes place. You don't need g here, since the pattern can only match once.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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