chriscrutt
chriscrutt

Reputation: 529

Using grep to search for a whole word/phrase with only part

I am trying to fetch the current "Device Node" (for example disk0s4) for my Bootcamp partition on my MacBook Pro using the terminal command $ diskutil info "BOOTCAMP" | grep "Node". This works nicely. I want to create a program that does a few things to the partition/volume and because it could potentially change nodes (because I screw with my filesystem).

Thus I need to create a variable or store the value of the device node (and only the device node) so I can use it later. Here is what I have tried.

$ grepVar=$(diskutil info "BOOTCAMP" | grep "Node")
$ A="$(cut -d'/' -f1 <<<"$grepVar")"
$ echo "$A hi"
   Device Node:               hi

The actual file reads as this when I run diskutil info "BOOTCAMP" | grep "Node":

Device Node: /dev/disk0s4

Obviously the cut cut out the wrong part, and kept the spacing. I experimented with a few other techniques but with no prevail. What would anyone recommend? The -o method just gave me part of the /dev/disk0s4, not the entire phrase/word. Would I just have to phrase it after "grepping" it? How?

Thanks a ton

Upvotes: 0

Views: 341

Answers (2)

ghoti
ghoti

Reputation: 46836

Remember that grep is an acronym. Global Regular Expression Print -- like the command you might use in vi to list lines that match a regex. Extra functionality like PCRE is not portable and may not be available in all systems -- or even in yours without software being installed.

Often sed provides the quickest or most succinct way to manipulate a stream of text. For example:

diskutil info "BOOTCAMP" | sed -ne '/Device Node:/s#.*/##p'

This finds the line of text you're looking at, strips off everything up to the last slash, and prints the remainder of the line. Putting this in a variable is as simple as:

node=$(diskutil info "BOOTCAMP" | sed -ne '/Device Node:/s#.*/##p')

or

read -r node < <(diskutil info "BOOTCAMP" | sed -ne '/Device Node:/s#.*/##p')

You could alternately process the output in awk like so:

diskutil info "BOOTCAMP" | awk -F/ '/Device Node:/ { print $NF }'

This, again, finds the line you're interested in, and prints the last field .. with field separators set to the forward slash.

If you REALLY wanted to use only grep for this, you could do some pipe-fitting:

diskutil info "BOOTCAMP" | grep 'Device Node:' | grep -o '/[^/]*$' | grep -Eo '[^/]+'

And of course, the final grep could be replaced with cut -d/ -f2 if you wish.

Naturally, all of these fail if BOOTCAMP doesn't exist.

Upvotes: 1

nbari
nbari

Reputation: 26915

In macOS you could use pcregrep, for example, to only obtain disk0s4:

echo "Device Node: /dev/disk0s4" | pcregrep -o "/dev/\K.*"

It will return:

disk0s4

The option -o is for showing only the part of the line that matched a pattern instead of the whole line.

The \K can be read as excluding everything to the left before it and return only the right part.

Upvotes: 0

Related Questions