The following one-liner seems to work. It prints all block device names except those which have a TYPE, PTTYPE, LABEL, or PARTLABEL. The last two on the grounds that something with a label is likely to be in use already.
This seems to me to be a much better approach than using grep -v to exclude a list of filesystem types known at this moment in time.
blkid | awk -F': ' '!/ ((PT)?TYPE|(PART)?LABEL)="[^"]+"/ {print $1}'
Note: the list of block devices produced by this are NOT in any way guaranteed not to be in use, just that they don't have any of the commonly used markers that in-use block devices have. They're probably not in use, but without spending significantly more time researching the issue I'm extremely reluctant to even suggest that it is any kind of guaranteed list.
On one of my ZFS On Linux boxes, it produces the following output:
# blkid | awk -F': ' '!/ ((PT)?TYPE|(PART)?LABEL)="[^"]*"/ {print $1}'
/dev/sdb9
This is correct for that system. /dev/sdb9 IS an unformatted, unused partition. It's an 8MB partition at the end of a disk which is used in a single-disk ZFS pool (this is a home machine for testing stuff and I needed its mirror drive for something else and haven't got around to replacing it yet)
BTW, blkid takes significantly longer to run than lsblk. It does a lot more work trying to identify what kind of block device it's looking at.
This is probably only noticeable on servers with hundreds of drives/lvm members/zvols and other block devices.
For example, on one of my medium-sized servers (with 362 block devices of various kinds), blkid takes about 2 minutes to run, while lsblk takes about 0.09 seconds. On another, much smaller, system with only 39 block devices (the home testing box mentioned above), blkid takes 0.16 seconds while lsblk takes 0.01 seconds.
If you need to run this repeatedly and the run-time is too long, you can always cache blkdid's output in a tmpfile for a short time. e.g. if the cache either doesn't exist or is older than, say, 30 minutes then generate the cache file (blkid > /path/to/blkid.cache) and use that as the input to awk or whatever.