我有一个短bash脚本输出系统上的安装的设备:
#!/bin/bash
{
regex="^(\/dev\S+) \S+ (\/\S+) \S+ (\S+)"
echo "Device Mount Type"
mount | pcregrep -o1 -o2 -o3 --om-separator=" " "$regex" | sort
} | column -t -o" | "
我的输出是:
Device | Mount | Type
/dev/md1 | /boot/efi | vfat
/dev/md2 | /boot | xfs
/dev/md4 | /home | xfs
/dev/md5 | /data | xfs
/dev/nvme0n1p2 | /tmp | xfs
我想看到的是:
Device | Mount | Type
---------------+-----------+-----
/dev/md1 | /boot/efi | vfat
/dev/md2 | /boot | xfs
/dev/md4 | /home | xfs
/dev/md5 | /data | xfs
/dev/nvme0n1p2 | /tmp | xfs
这是困难的,因为列的宽度变化,而且非常最后一列没有在最后一个分隔符。
前两列的宽度可以从第一行来确定。但最后一列的宽度只能通过评估每一行,并找到最宽的确定。
什么是一些简单的方法来做到这一点?
作为一个纯粹的bash解决方案,请尝试以下方法:
#!/bin/bash
maxlen=0
lines=()
while read -r line; do
sub1=${line%%|*}}
s1=${#sub1}
sub2=${line%|*}
s2=${#sub2}
if ((${#line} > maxlen)); then
maxlen=${#line}
fi
lines+=("$line")
done < <(
{
regex="^(\/dev\S+) \S+ (\/\S+) \S+ (\S+)"
echo "Device Mount Type"
mount | pcregrep -o1 -o2 -o3 --om-separator=" " "$regex" | sort
} | column -t -o" | ")
f1=$((s1-1)) # field width for "Device"
f2=$((s2-s1)) # field width for "Mount"
f3=$((maxlen-s2-1)) # field width for "Type"
echo "${lines[0]}"
printf "%*s+" "$f1" | tr " " "-"
printf "%*s+" "$f2" | tr " " "-"
printf "%*s\n" "$f3" | tr " " "-"
for ((i=1; i<${#lines[@]}; i++)); do
echo "${lines[$i]}"
done
输出:
Device | Mount | Type
---------------+-----------+-----
/dev/md1 | /boot/efi | vfat
/dev/md2 | /boot | xfs
/dev/md4 | /home | xfs
/dev/md5 | /data | xfs
/dev/nvme0n1p2 | /tmp | xfs
我承认,这将是更优雅和清晰利用其他语言赛勒斯。