Bash – How to list the info for an array of /dev/disks using bash expansion or substitution

bashbrace-expansioncommand linecommand-substitutionosx

I want the output of:

diskutil list; diskutil info [multiple devices]

Without having to do:

diskutil info disk0; diskutil info disk0s1; diskutil info disk1 …etc

For example, with many builtin commands like touch rm mkdir, etc. I can use bracket expansion to perform commands on multiple versions of a file:

mkdir njboot0{1,2,3}

Or, when searching, I can use special characters to specify matching specific patterns in a string, like:

find ~/ -type f \( -name *mp3 -or -name *mp4 \)

But:

diskutil info disk{0,0s1,1,1s1}    #syntax error

diskutil info /dev/*               #syntax error

(diskutil info disk$'')$'0|1|2'    #syntax error

diskutil info disk\(0,s0\)         #syntax error

etc…

diskutil info disk${disk}'0'$'s1'  #okay, getting somewhere. this works at least. 
  1. How do I perform the diskutil command mentioned above on multiple disks correctly?
  2. Is there any general syntax I can follow for expansion/substitution?

As requested, this is the output of diskutil list:

/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *1.0 TB     disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                  Apple_HFS Macintosh HD            999.7 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3

Best Answer

The brace expansion you're asking about will only expand for files/directories that match on disk to the pattern you use. The other issue you'll run into is diskutil may not be able to handle more than 1 argument at a time. To expand these you'd need to do a while or for loop, and pass the results to diskutil as you iterate through the loop.

Example

$ for i in /dev/*; do diskutil "$i";done

As to your 2nd question there isn't really any method where brace expansion can help you in situations where there are no corresponding files/directories on disk.

Parsing diskutil

Given the output from this command you'll have to resort to using a tool such as awk, sed, or grep to "parse" this output so that you can get meaningful information about the disks, for further queries calling diskutil a 2nd time.

Example

Here's a rough cut of parsing the output from diskutil using grep and sed. There are more efficient ways to do this but this shows you the general approach.

$ diskutil list | grep -E "[ ]+[0-9]+:.*disk[0-9]+" | sed 's/.*\(disk.*\)/\1/'
disk0
disk0s1
disk0s2
disk0s3

With this approach you can then modify the for loop above like so:

$ for i in $(diskutil list | grep -E "[ ]+[0-9]+:.*disk[0-9]+" | \
    sed 's/.*\(disk.*\)/\1/'); do diskutil info $i; done
Related Question