Home > Software design >  Using sed on Bash Command
Using sed on Bash Command

Time:06-26

I'm trying to get a list of devices on my linux box from normal bash commands in a script. I've used the following however it isn't working. Ideally, I'd like to get all sd* and nvme devices into an array. This is what I have tried:

lsblk --nodeps | sed -n '/sd\.*/p'
lsblk --nodeps | sed '/(sd | nv)\.*/p'
lsblk --nodeps | sed -n 's/^([a-z0-9] ?).*/\1/'
lsblk --nodeps | sed -n '/^.*?/p'
lsblk --nodeps | sed '/^(. ?)\s*/p'
lsblk --nodeps | sed '/^(s. ?|n. ?)?)\s*/p'

This is the starting syntax:

$ lsblk --nodeps
NAME    MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda       8:0    0 119.2G  0 disk
sdb       8:16   1  57.8G  0 disk
nvme0n1 259:0    0 232.9G  0 disk

So I want to regex for sd* and nvme, without the trailing spaces.

Any insight appreciated how I can get drives into an array.

CodePudding user response:

Making lsblk Output Easier To Parse

lsblk can be told to suppress a header line, and to emit only the specific pieces of data you care about -- in this case, device names.

If you have a listing with nothing but device names, grep is the easiest tool to use to parse them; but to add an additional rule (in this case, discarding partitions), awk comes into play.

Thus:

readarray -t disks < <(lsblk -dnr --output NAME | grep '^(sd|nvme)')

Filtering /dev/disk/by-id Yourself

For the stubborn, to show that it can be done:

shopt -s nullglob extglob
declare -A results=( )
devices=( /dev/disk/by-id/!(*-part*) )
for device in "${devices[@]}"; do
  target=$(readlink -f "$device")
  results[${target#/dev/}]=1
done
disks=( "${!results[@]}" )
declare -p disks # print the resulting array
  • Related