lsblk
排序顺序lsblk
按照很难遵循的顺序对分区进行排序。一种不需要编写bash脚本或python脚本就能对其进行排序的方法将是首选。
Unix &Linux中也提出了类似的问题:
但是,使用-x NAME
参数进行排序的答案会导致树缩进消失。
lsblk
现在是这样显示的:
$ lsdrv
NAME FSTYPE LABEL MOUNTPOINT SIZE MODEL
nvme0n1 477G Samsung SSD 960 PRO 512GB
├─nvme0n1p9 swap [SWAP] 7.9G
├─nvme0n1p7 ext4 Old_Ubuntu_16.04 /mnt/old 23.1G
├─nvme0n1p5 ntfs 859M
├─nvme0n1p3 16M
├─nvme0n1p1 ntfs 450M
├─nvme0n1p8 ntfs Shared_WSL+Linux /mnt/e 9G
├─nvme0n1p10 ext4 Ubuntu_18.04 /mnt/clone 27.2G
├─nvme0n1p6 ext4 New_Ubuntu_16.04 / 45.1G
├─nvme0n1p4 ntfs NVMe_Win10 /mnt/c 363.2G
└─nvme0n1p2 vfat /boot/efi 99M
mmcblk0 119.1G
└─mmcblk0p1 vfat SANDISK128 /media/rick/SANDISK128 119.1G
sr0 1024M DVD+/-RW DW316
sda 931.5G HGST HTS721010A9
├─sda4 ntfs WINRETOOLS 450M
├─sda2 128M
├─sda5 ntfs Image 11.4G
├─sda3 ntfs HGST_Win10 /mnt/d 919G
└─sda1 vfat ESP 500M
这是如何对lsblk
进行排序的:
$ lsdrv
NAME FSTYPE LABEL MOUNTPOINT SIZE MODEL
nvme0n1 477G Samsung SSD 960 PRO 512GB
├─nvme0n1p1 ntfs 450M
├─nvme0n1p2 vfat /boot/efi 99M
├─nvme0n1p3 16M
├─nvme0n1p4 ntfs NVMe_Win10 /mnt/c 363.2G
├─nvme0n1p5 ntfs 859M
├─nvme0n1p6 ext4 New_Ubuntu_16.04 / 45.1G
├─nvme0n1p7 ext4 Old_Ubuntu_16.04 /mnt/old 23.1G
├─nvme0n1p8 ntfs Shared_WSL+Linux /mnt/e 9G
├─nvme0n1p9 swap [SWAP] 7.9G
└─nvme0n1p10 ext4 Ubuntu_18.04 /mnt/clone 27.2G
mmcblk0 119.1G
└─mmcblk0p1 vfat SANDISK128 /media/rick/SANDISK128 119.1G
sr0 1024M DVD+/-RW DW316
sda 931.5G HGST HTS721010A9
├─sda1 vfat ESP 500M
├─sda2 128M
├─sda3 ntfs HGST_Win10 /mnt/d 919G
├─sda4 ntfs WINRETOOLS 450M
└─sda5 ntfs Image 11.4G
注: lsdrv
是在~/.bashrc
中定义的别名:
$ alias lsdrv
alias lsdrv='lsblk -o NAME,FSTYPE,LABEL,MOUNTPOINT,SIZE,MODEL |egrep -v "^loop"'
更改排序顺序的复杂性如下:
├─
和└─
的分区才在它们的驱动器下排序。├─
替换为└─
。└─
替换为├─
。10
放在1
,E.G. 1
,然后10
然后2
之后。真正的9
应该出现在10
之前。多年来,lsblk
的排序一直是个棘手的问题。希望有人有一个使用GNU的简单解决方案,比如:awk
、sed
、grep
、uniq
和/或sort
等等。
发布于 2022-02-12 22:50:48
最后,我编写了一个通用排序函数来解决这个问题。
lsblk
排序顺序$ lsdrv | sblk
NAME FSTYPE LABEL MOUNTPOINT SIZE MODEL
nvme0n1 477G Samsung SSD 960 PRO 512GB
├─nvme0n1p1 ntfs 450M
├─nvme0n1p2 vfat /boot/efi 99M
├─nvme0n1p3 16M
├─nvme0n1p4 ntfs NVMe_Win10 /mnt/c 363.2G
├─nvme0n1p5 ntfs 859M
├─nvme0n1p6 ext4 New_Ubuntu_16.04 / 45.1G
├─nvme0n1p7 ext4 Old_Ubuntu_16.04 /mnt/old 23.1G
├─nvme0n1p8 ntfs Shared_WSL+Linux /mnt/e 9G
├─nvme0n1p9 swap [SWAP] 7.9G
└─nvme0n1p10 ext4 Ubuntu_18.04 /mnt/clone 27.2G
mmcblk0 119.1G
└─mmcblk0p1 vfat SANDISK128 /media/rick/SANDISK128 119.1G
sr0 1024M DVD+/-RW DW316
sda 931.5G HGST HTS721010A9
├─sda1 vfat ESP 500M
├─sda2 128M
├─sda3 ntfs HGST_Win10 /mnt/d 919G
├─sda4 ntfs WINRETOOLS 450M
└─sda5 ntfs Image 11.4G
lsblk
输出进行排序
花了几个小时搜索不同的bash命令才能找到解决方案。bash脚本(最初称为sblk
)可以用于其他目的:
#!/bin/bash
# Ask Ubuntu: https://askubuntu.com/questions/1392560/how-to-change-lsblk-sort-order
oIFS="$IFS" # Save IFS
IFS='|' # Use "|" as array delimiter
declare -a partiions=() # Partitions array for a given drive
add_part () {
line="$1" # Confusing parameter $1 becomes obvious
part=${line%% *} # get partition name, then get number
key=$(echo "$part" | grep -Eo '[0-9]+)
# If length of number is less than 2, prepend "0"
if [[ "${#key}" < 2 ]]; then
key="0$key" # Prepend "0" to single digit
fi
line="${line:2}" # Strip out tree character
partitions+=( "$key$line" ) # Old line "├─..." now array entry "99..."
}
sort_parts () {
# Sort partitions array with sort key into new "sorted" array
read -r -d '' -a sorted < <(
echo "${partitions[*]}" | tr "|" "\n" | sort | tr "\n" "|" )
last_i=$(( ${#sorted[@]} - 1 )) # Last 0-based index in sorted array
for ((i=0; i <= $last_i; i++)); do
line="${sorted[i]}" # Get array line at 0-based index
line="${line:2}" # Strip out sort key "99"
if [[ $i -lt $last_i ]]; then
echo "├─$line" # Print a line that is not the last line
else
echo "└─$line" # Print last line
fi
done
partitions=() # Empty partitions array for the next drive
}
# Main Loop
while read line
do
first="${line:0:2}"
if [[ "$first" == "├─" || "$first" == "└─" ]]; then
add_part "$line" # Add special line to partitions array
if [[ "$first" == "└─" ]]; then
sort_parts # Last partition. Sort and print array
fi
else
echo "$line" # Simply print a regular line
fi
done < "${1:-/dev/stdin}" # Read from file $1 or from standard input
IFS="$oIFS" # Restore old IFS
https://askubuntu.com/questions/1392560
复制相似问题