AWK formatting Disk Utility command formatting incorrectly

0

I am trying to learn awk at the moment and so I am trying it on the disk utility command.

Here is the output when I run Disk Utility list disk0

/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *251.0 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                  Apple_HFS Macintosh HD            145.4 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3
   4:           Linux Filesystem                         48.0 GB    disk0s4
   5:       Microsoft Basic Data WINDOWS                 38.0 GB    disk0s5
   6:                 Linux Swap                         18.8 GB    disk0s6

Now if I run diskutil list disk0 | awk 'NR > 2 {print}' I get this as my output.

   0:      GUID_partition_scheme                        *251.0 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                  Apple_HFS Macintosh HD            145.4 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3
   4:           Linux Filesystem                         48.0 GB    disk0s4
   5:       Microsoft Basic Data WINDOWS                 38.0 GB    disk0s5
   6:                 Linux Swap                         18.8 GB    disk0s6

As you can see the output is as expected. The issue now is when I try printing $2,$3 and $4, The output sometimes prints 'HD' when it should print the size and other issues like this.

diskutil list disk0 | awk 'NR > 2 {print $1}'

0:
1:
2:
3:
4:
5:
6:

Expected result

diskutil list disk0 | awk 'NR > 2 {print $2}'

GUID_partition_scheme
EFI
Apple_HFS
Apple_Boot
Linux
Microsoft
Linux

Expected result

GUID_partition_scheme
EFI
Apple_HFS
Apple_Boot
Linux Filesystem
Microsoft Basic Data
Linux Swap

As you can see the command outputs as expected until the Linux Filesystem. This is due to there being spaces in the word?

This now affects everything else that comes after it, for example

diskutil list disk0 | awk 'NR > 2 {print $3}' displays

*251.0
EFI
Macintosh
Recovery
Filesystem
Basic
Swap

when it should show

EFI
Macintosh HD
Recovery HD

Windows

How would I get AWK to format as I would expect?

iProgram

Posted 2015-09-01T10:27:46.453

Reputation: 505

Answers

1

diskutil output is formatted with multiple spaces to output in neat columns. Extract the fields required using awk's substr function.

For example to extract the type and name from diskutil. The substr functions extract the fields from the diskutil output. For example, the name field begins at position 6 and is up to 27 chars long. The gsub functions merely strip leading and trailing white space from the fields.

diskutil list disk0 | awk 'NR > 2 {
   name=substr($0, 33,20);  # name field - position 33, length 20 chars
   gsub(/ /,"",name)    # trim spacing

   type=substr($0, 6, 27);  # type field - position 6, length 27 chars
   gsub(/ /,"",type)    # trim spacing
   print "name="name," type="type
}' 

suspectus

Posted 2015-09-01T10:27:46.453

Reputation: 3 957

That has not changed the output at all. – iProgram – 2015-09-01T10:46:12.537

Answer has been revised. – suspectus – 2015-09-01T10:58:13.330

That prints out the filed correct, however I now can't use awk to format the whole output. – iProgram – 2015-09-01T11:04:06.067

Answer now edits the fields directly in awk using substr function. – suspectus – 2015-09-01T11:24:16.317

@iProgram, you're talking about "format the whole output". How does that fit into what you asked? – glenn jackman – 2015-09-01T13:49:50.917

I want it so I can say 'The partition $1 is formatted to $2 and is called $3' etc. This only gives me one column. – iProgram – 2015-09-01T18:00:12.830

As you say you are learning awk at the moment - it would not be too difficult to finish the script. The answer demonstrates how to extract the info you need - you just need to extend it to suit your precise requirements. If you have further issues you can always post another question. – suspectus – 2015-09-01T18:30:43.513

Could you edit your comment and explain what each command is doing? I don't get all the numbers, Would I have to know the length of the fields in advanced or not? If not how would I create them dynamically? – iProgram – 2015-09-01T18:41:45.377

I've added more explanation. Yes you need to determine the positions of the field(s) - not difficult as you have the output from diskutil. Any editor would help determine the field position and length you need. I think you only require one more field to complete the task. – suspectus – 2015-09-01T20:04:50.473

1

With bash you can do:

diskutil list disk0 | { read; read; while read i; do echo ${i:6:27}; done; }
  • The first two reads are to ignore the first to lines.
  • The while loop reads the input line by line and prints the desired part.

Edit: If it must be awk, use this:

diskutil list disk0 | awk 'NR>2{$0=substr($0,6,27);sub("^ +","",$0);print}'
  • NR>2 omits the first two line in the output
  • substr() cuts the relevat part
  • sub() removes the leading spaces
  • and finally print prints the line

chaos

Posted 2015-09-01T10:27:46.453

Reputation: 3 704

That works, however I cannot use awk to format the whole output. – iProgram – 2015-09-01T11:04:44.210

@iProgram I edited my answer, see the awk solution – chaos – 2015-09-01T11:29:47.247

@iProgram I don't understand, you have now an awk and a non-awk solution, whats the problem? – chaos – 2015-09-01T11:50:24.993

I think the OP wants to print other fields as well ("whole output"). For that he'd have to determine the column numbers and extract them with substr() like shown. – user1016274 – 2015-09-01T17:43:05.330

@user1016274 was correct. I want to do it like this 'partition $1 is formatted to $2' etc. Thats why I want to have all the output. – iProgram – 2015-09-01T17:59:02.710