12

My goal is to get the disks greater than 100G from lsblk.

I have it working, but it's awkward. I'm pretty sure it can be shortened. Either by using something totally different than lsblk, or maybe I can filter human readable numbers directly with awk.

Here's what I put together:

lsblk | grep disk | awk '{print$1,$4}' | grep G | sed 's/.$//' | awk '{if($2>100)print$1}'

It outputs only the sdx and nvmexxx part of the disks larger than 100G. Exactly what I need.

I am happy with it, but am eager to learn more from you Gurus 😉

  • between 100-999GB and larger than 100T, but nothing between 1-99T, i presume? (terabytes~) – hanshenrik Aug 2 '19 at 21:13
  • Yes that is one flaw that slipped my attention and was already discussed in the answers. I therefore accepted the answer to do the filter based on byte size instead of human readable. If you of another method I'll be happy to learn about that to. – chalybeum Aug 2 '19 at 21:47
28

You can specify the form of output you want from lsblk:

% lsblk -nblo NAME,SIZE
mmcblk0   15931539456
mmcblk0p1   268435456
mmcblk0p2 15662038528

Options used:

-b, --bytes
      Print the SIZE column in bytes rather than in human-readable format.

-l, --list
      Use the list output format.

-n, --noheadings
      Do not print a header line.

-o, --output list
      Specify which output columns to print.  Use --help to get a list of  all  supported
      columns.

Then the filtering is easier:

% lsblk -nblo NAME,SIZE | awk '$2 > 4*2^30 {print $1}' # greater than 4 GiB
mmcblk0
mmcblk0p2

In your case, that'd be 100*2^30 for 100GiB or 100e9/1e11 for 100GB.

  • Uhhh, that's clever! Weeding out what's not needed in the first place. One question: You're using x*2**30 just for consistency with the bytes? Would there be drawback to use s.th. like 10**3? – chalybeum Aug 1 '19 at 10:44
  • @chalybeum yes, for bytes. No, you can use 10**9. The values don't differ all much. – muru Aug 1 '19 at 10:50
  • Note that OP is filtering out partitions in the one-liner. – UncleCarl Aug 1 '19 at 19:59
  • @UncleCarl noted – muru Aug 1 '19 at 20:00
  • 1
    Note that in this particular case of 100G boundary awk could also be shortened to egrep '\d{12,}' to remove lines with <12 digits in a sequence. Awk is of course more universal. – Gnudiff Aug 2 '19 at 7:04
18

You can also tell lsblk to output in JSON format and do the filtering with jq:

$ lsblk -Jb | jq -r '..|select(.size? >= 1e11).name'
sda
sda2

Or:

$ lsblk -Jb | jq -r '..|select(.type? == "disk" and .size? >= 1e11).name'
sda

To limit to entries of type disk.

(1e11 being 100 GB. Replace with 107374182400 (or 100*1024*1024*1024) for 100 GiB. Because of rounding, lsblk itself without -b reports 100G for sizes ranging from about 99.9278 to 100.0488 GiB (for some reason))

With lsblk -OJb, lsblk reports all available information which lets you do a more fined-grained selection or output more or more relevant information.

You could also get the information directly from /sys. With zsh:

$ printf '%s\n' /sys/class/block/*(e'[(($(<$REPLY/size) * 512 >= 1e11))]':t)
sda
sda2
  • This is a true answer from a Guru, no one will be able to read it. :D – Archemar Aug 1 '19 at 14:50
  • I take this as a nice to know. But at this stage of my journey in bash I don't want to introduce further complexity by using yet another tool. – chalybeum Aug 2 '19 at 6:13
  • That's a nice application of jq (which I learned about only some months ago). – Dubu Aug 2 '19 at 9:47
6

try

lsblk| awk '$4 ~ /G$/ && $4+0 > 100 {print $1}'

this will grep and filter at same time.

  • $4 ~ /G$/ get filed with size in G
  • $4+0 > 100 get size over 100G
  • {print $1} print NAME

as a rule you should never need to use grep and awk in same pipe.

to get only disk (and no partition) : awk filtering

lsblk| awk '$4 ~ /G$/ && $4+0 > 100 && $6 == "disk"  {print $1}'

where

  • $6 == "disk" select only column with disk

to get only disk (and no partition) : lsblk filtering

lsblk --nodeps| awk '$4 ~ /G$/ && $4+0 > 100 {print $1}'

where

  • --nodeps : -d, --nodeps don't print slaves or holders
  • Almost there. It still prints partitions. But I think I can get behind that when I have a bit free time. – chalybeum Aug 1 '19 at 10:34
  • 1
    @chalybeum I fixed that, same filtering trick can be applied to muru's answer. – Archemar Aug 1 '19 at 12:36
  • (Though I'd probably use the --no-deps option, in keeping with the general style of that answer) – muru Aug 1 '19 at 13:00
  • 2
    I'm afraid this will fail to catch disks whose size is shown in terabytes (or bigger units). – fra-san Aug 1 '19 at 15:11
  • @fra-san fair point and is also true for my original solution. So I'm taking the disk filter bit from here and put it in the byte conversion. – chalybeum Aug 2 '19 at 6:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.