Search code examples
regexbashawkgreplinux-disk-free

List Volumes with DF, Grep, Awk | Bash Shell


Trying to print all entries which start with /Volumes/, this to list mounted volumes on mac. See Updates.

IFS=$'\n' read -r -d '' -a volumes < <(
  df  | egrep -o '/Volumes/.*'
)

echo "${volumes}"

Update 1: This worked, but prints a space before each new line.

#!/usr/bin/env bash


IFS=$'\n' read -r -d '' -a volumes < <(
  df | egrep -oi '(\s+/Volumes/\S+)'
)

printf "%s\n" "${volumes[@]}"

Update 2: Worked, but doesn't print volume names with spaces in it

IFS=$'\n' read -d '' -ra volumes < <(
df | awk 'index($NF, "/Volumes/")==1 { print $NF }'
)

printf '%s\n' ${volumes[@]}

Update 3: Prints the second part of the volume name with spaces in it on a new line

IFS=$'\n' read -d '' -ra volumes < <(
df | awk -F ' {2,}' 'index($NF, "/Volumes/")==1 { print $NF }'
)

printf '%s\n' ${volumes[@]}

Solution:

Tested Platform: macOS Catalina

IFS=$'\n' read -d '' -ra volumes < <(
df | sed -En 's~.* (/Volumes/.+)$~\1~p'
)

printf '%s\n' "${volumes[@]}"

DF Output

Filesystem    512-blocks       Used  Available Capacity iused       ifree %iused  Mounted on
/dev/disk1s5   976490576   21517232  529729936     4%  484332  4881968548    0%   /
devfs                781        781          0   100%    1352           0  100%   /dev
/dev/disk1s1   976490576  413251888  529729936    44%  576448  4881876432    0%   /System/Volumes/Data
/dev/disk1s4   976490576   10487872  529729936     2%       6  4882452874    0%   /private/var/vm
map auto_home          0          0          0   100%       0           0  100%   /System/Volumes/Data/home
/dev/disk7s1       40880       5760      35120    15%     186  4294967093    0%   /private/tmp/tnt12079/mount
/dev/disk8s1       21448       1560      19888     8%       7  4294967272    0%   /Volumes/usb drive
/dev/disk6s1  9766926680 8646662552 1119135456    89%   18530 48834614870    0%   /Volumes/root
/dev/disk2s1    60425344   26823168   33602176    45%  419112      525034   44%   /Volumes/KINGS TON

Solution

  • You may use this pipeline in OSX:

    IFS=$'\n' read -d '' -ra volumes < <(
    df | sed -En 's~.* (/Volumes/.+)$~\1~p'
    )
    

    Check array content:

    printf '%s\n' "${volumes[@]}"
    

    or

    declare -p volumes
    

    declare -a volumes=([0]="/Volumes/Recovery" [1]="/Volumes/Preboot")