使用 DF、Grep、Awk 列出卷 | Bash Shell

List Volumes with DF, Grep, Awk | Bash Shell

正在尝试打印所有以 /Volumes/ 开头的条目,以列出 mac 上已安装的卷。请参阅更新。

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

echo "${volumes}"

更新 1:这有效,但在每个新行之前打印 space。

#!/usr/bin/env bash


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

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

更新 2:有效,但不打印包含 space 的卷名称

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

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

更新 3:在新行上打印卷名的第二部分,其中包含 spaces

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

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

解法:

测试平台: macOS Catalina

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

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

DF输出

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

您可以使用

IFS=$'\n' read -r -d '' -a volumes < <(
  df -h | awk 'NR>1 &&  ~ /^\/Volumes\//{print }'
)
printf "%s\n" "${volumes[@]}"

awk 命令获取除第一行 (NR>1) 以外的所有行,其中字段 6 ("Mounted on") 以 /Volumes/ 开头(请参阅 ~ /^\/Volumes\/),然后打印字段 6 的值。

printf "%s\n" "${volumes[@]}" 命令将在单独的行上打印 volumes 数组中的所有项目。

如果卷路径恰好包含spaces,您可以检查是否有数字后跟%后跟白色spaces和/Volume/和然后使用 space:

加入以字段 6 开头的字段
df -h | awk 'NR>1 && [=11=] ~ /[0-9]%[ \t]+\/Volumes\//{for (i=6;i<=NF;i++) {a=a" "$i}; print a}'

您可以在 OSX 中使用此管道:

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

检查数组内容:

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

declare -p volumes

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

有点不清楚你想要什么输出,但你总是可以使用 awk 来解析信息。例如,如果您想要 "Filesytem" 和 "Mounted on" 信息,您可以使用 with df:

df | awk '{
    for (i=1; i<=NF; i++)
        if ($i ~ /^\/Volumes/) {
            print , substr([=10=], match([=10=],/\/Volumes/))
            break
        }
    }'

或者使用您在文件 dfout 中提供的输入,您可以将文件读取为:

awk '{
    for (i=1; i<=NF; i++)
        if ($i ~ /^\/Volumes/) {
            print , substr([=11=], print , substr([=11=], match([=11=],/\/Volumes/)))
            break
        }
}' dfout

示例输出

将文件 dfout 与您的数据一起使用,您将收到:

/dev/disk8s1 /Volumes/usb drive
/dev/disk6s1 /Volumes/root
/dev/disk2s1 /Volumes/KINGS TON

如果您需要更多或更少的每条记录,您可以在 print 语句中输出您喜欢的任何其他字段。

如果您想要不同的格式或输出,请告诉我,我们很乐意进一步提供帮助。我没有要测试的 Mac,但是使用的函数是标准的 awk 而不是 GNU awk 特定的。