【问题标题】:List Volumes with DF, Grep, Awk | Bash Shell使用 DF、Grep、Awk 列出卷 |重击壳
【发布时间】:2024-01-18 04:29:02
【问题描述】:

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

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

echo "${volumes}"

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

#!/usr/bin/env bash


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

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

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

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

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

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

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/.+)$~\1~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

【问题讨论】:

  • (1) 您的read 创建了一个array 变量,每个元素都有一个输入行。 ${volumes} 仅扩展到第一个元素(下标 0);使用${volumes[@]} 或可能${volumes[*]} (2) 数组中的每一行/元素应该 是一个匹配的字符串,我不知道为什么它不是。手动查看df | egrep -o ...,看看是否正确。
  • 尝试 df | egrep -o '(^/Volumes/\S+)'df | egrep -o '(\s+/Volumes/\S+)' 取决于您想要的列(使用 -i 表示不区分大小写)
  • 请看更新,空白问题
  • 它没有打印任何空间。试试我的解决方案。
  • 这适用于文件名中的空格df | egrep -oi '(\s+/Volumes/.*)' | egrep -o '(/.*)'

标签: regex bash awk grep linux-disk-free


【解决方案1】:

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

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

检查数组内容:

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

declare -p volumes

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

【讨论】:

  • 感谢@anubhava 的回答,当 di 做 echo ${volumes[@]} 时,它会将所有卷打印在一行上?
  • 谢谢,它成功了,唯一的问题是它不会列出名称中带有空格的卷。
  • 顺便说一句,你的 grep 命令也使用了\s+/Volumes/\S+,它不会找到带空格的卷。
  • 是的,我知道,这对于在卷中使用空格的人来说是个问题,我不这样做,但有些人会这样做。
  • 它产生相同的输出。与之前的编辑一样。
【解决方案2】:

你可以使用

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

awk 命令获取除第一行 (NR&gt;1) 之外的所有行,并且字段 6(“Mounted on”)以 /Volumes/ 开头(请参阅$6 ~ /^\/Volumes\/),然后打印字段 6 值.

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

如果卷路径恰好包含空格,您可以检查是否有一个数字后跟%,后跟空格和/Volume/,然后用空格连接以字段6开头的字段:

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

【讨论】:

  • 谢谢你——它成功了。但是当我重命名(其中有空格)一卷时,它只拾取了其中的第一个单词(King)而不是(King ston)?
  • @Adrian 你把它重命名为什么?不要使用空格。我从不在 Linux 中的文件和文件夹名称中使用空格。
  • 我也从不使用它,只是希望它能够工作以防有人使用空格
  • @Adrian 然后使用df -h | awk 'NR&gt;1 &amp;&amp; $0 ~ /[0-9]%[ \t]+\/Volumes\//{for (i=6;i&lt;=NF;i++) {a=a" "$i}; print a}'
  • @Adrian 我也添加了空格的解决方案
【解决方案3】:

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

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

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

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

示例输出

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

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

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

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

【讨论】: