The following function searches for disks whose partitions all have an attribute that match a filter when listed with lsblk
. Comments are in TomDoc format.
# Public: finds drives in /dev/sd* whose partitions all have an attribute that matches a filter.
#
# $1 - filter (default: '.*')
# $2 - attribute (default: 'MOUNTPOINT')
#
# Returns full paths to disks whose attributes match the filter
#
# Examples
# lsblk /dev/sda -oTYPE,PATH,MOUNTPOINTS --pairs
# # TYPE="disk" PATH="/dev/sda" MOUNTPOINTS=""
# # TYPE="part" PATH="/dev/sda1" MOUNTPOINTS="/boot/efi"
# # TYPE="part" PATH="/dev/sda2" MOUNTPOINTS="/var/snap/firefox/common/host-hunspell\x0a/"
# lsblk_disk_filter '(/var/snap/firefox/common/host-hunspell\\x0a/|/boot/efi)' 'MOUNTPOINTS'
# # /dev/sda
#
# lsblk /dev/sda -oTYPE,PATH,FSTYPE --pairs
# # TYPE="disk" PATH="/dev/sda" FSTYPE=""
# # TYPE="part" PATH="/dev/sda1" FSTYPE="vfat"
# # TYPE="part" PATH="/dev/sda2" FSTYPE="ext4"
# lsblk_disk_filter '(ext4|xfs|vfat)' 'FSTYPE'
# # /dev/sda
#
# REQUIRES lsblk >= 2.33 for PATH output option - https://github.com/util-linux/util-linux/blob/master/Documentation/releases/v2.33-ReleaseNotes#L372
# TODO: add support for /dev/nvme* (I don't have hardware to test this...)
lsblk_disk_filter () {
local filter="${1:-'.*'}";
local attribute="${2:-'MOUNTPOINT'}"
local PERLCMD='my ($type, $path, $attr) = /^TYPE\="([^"]*)"\s*PATH\="([^"]*)"\s*$col\="([^"]*)"\s*$/ or next; # VAR ASSIGNMENT \
if( $type=~/disk/i){ # CHECK IF TYPE IS DISK \
printf("%s ",$disk); # PRINTING LAST DISK \
$disk=$path; # ASSIGN NEXT DISK \
} elsif($attr!~/$filter/){ # PARTITION ATTRIBUTE MISMATCH TEST \
$disk=""; # DELETING DISK ON MISMATCH \
} END{ printf($disk); } # PRINT LAST DISK'
lsblk --pairs --noheadings --ascii -o TYPE,PATH,$attribute /dev/sd* | perl -s -wnl -E "${PERLCMD}" -- -filter="$filter" -disk='' -col=$attribute
# perl switch example: https://stackoverflow.com/questions/31155659/how-do-i-pass-command-line-options-to-a-perl-program-with-perl-e
# /dev/sdx describes SCSI/SATA devices, /dev/sdx\d+ describes their partitions.
# See the /dev/ naming convention described in the "devices" section in fdisk.
} # END lsblk_disk_filter
```