Reputation: 43
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
Upvotes: 1
Views: 1086
Reputation: 785276
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")
Upvotes: 1
Reputation: 84569
It's a little unclear just what output you want, but you can always use awk
to parse the information. For example if you want the "Filesytem" and "Mounted on" information, you can use with df
:
df | awk '{
for (i=1; i<=NF; i++)
if ($i ~ /^\/Volumes/) {
print $1, substr($0, match($0,/\/Volumes/))
break
}
}'
Or using the input you provided in the file dfout
, you could read the file as:
awk '{
for (i=1; i<=NF; i++)
if ($i ~ /^\/Volumes/) {
print $1, substr($0, print $1, substr($0, match($0,/\/Volumes/)))
break
}
}' dfout
Example Output
Using the file dfout
with your data you would receive:
/dev/disk8s1 /Volumes/usb drive
/dev/disk6s1 /Volumes/root
/dev/disk2s1 /Volumes/KINGS TON
If you need more or less of each record, you can just output whatever other fields you like in the print
statement.
Let me know if you want the format or output different and I'm happy to help further. I don't have a Mac to test on, but the functions uses are standard awk
and not GNU awk
specific.
Upvotes: 0
Reputation: 626926
You may use
IFS=$'\n' read -r -d '' -a volumes < <(
df -h | awk 'NR>1 && $6 ~ /^\/Volumes\//{print $6}'
)
printf "%s\n" "${volumes[@]}"
The awk
command gets all lines other than the first one (NR>1
) and where Field 6 ("Mounted on") starts with /Volumes/
(see $6 ~ /^\/Volumes\/
), and then prints the Field 6 value.
The printf "%s\n" "${volumes[@]}"
command will print all the items in the volumes
array on separate lines.
If the volume paths happen to contain spaces, you may check if there is a digit followed with %
followed with whitespaces and /Volume/
and then get join the fields starting with Field 6 with a space:
df -h | awk 'NR>1 && $0 ~ /[0-9]%[ \t]+\/Volumes\//{for (i=6;i<=NF;i++) {a=a" "$i}; print a}'
Upvotes: 1