display drives with lsblk -o name -lpn , extract string containing "sd" - linux

So I've looked all over the place for what to do here and just find "from file". I am looking to extract from a command output.
Task: display the absolute path names of disks beginning with the sd.
Current progress: displaying absolute path name of disks
[host /]$ lsblk -o name -lpn
/dev/sda
/dev/sda1
/dev/mapper/centos-root
/dev/sda2
/dev/md127
....
Desired output
/dev/sda
/dev/sda1
/dev/sda2
....
I've played around with cut, print, awk and sed.
Got syntax errors or no output.

grep
lsblk -o name -lpn | grep "/dev/sd"
awk
lsblk -o name -lpn | awk '/dev\/sd/{print}'
sed
lsblk -o name -lpn | sed -n '/\/dev\/sd/p'
Output:
/dev/sda
/dev/sda1
/dev/sda2

lsblk accepts arguments, so you can in many cases just as easily say
lsblk -no name -lp /dev/sd?
The ? is just wildcard match of a single character, so sda, sdb, ...
There is a potential pitfall. If you have more than 26 disks or you are working on a system that uses those unique disk identifiers. In which case you need to change the wildcard to an asterisk and filter out only the unique results,
lsblk -no name -lp /dev/sd* | sort -u
Output (for either command):
/dev/sda
/dev/sda1
/dev/sda2
/dev/sda3
/dev/sdb
/dev/sdb1
/dev/sdb2

Try with sed:
lsblk -o name -lpn |sed -n '/\/sd/p'

Related

How can I *only* get the number of bytes available on a disk in bash?

df does a great job for an overview. But what if I want to set a variable in a shell script to the number of bytes available on a disk?
Example:
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda 1111111111 2222222 33333333 10% /
tmpfs 44444444 555 66666666 1% /dev/shm
But I just want to return 33333333 (bytes available on /), not the whole df output.
You may get exact number of bytes with df:
df -B1 /
Filesystem 1B-blocks Used Available Use% Mounted on
/dev/mapper/cl-root 32893632512 13080072192 18119061504 42% /
You may use awk,
df | awk '$1=="/dev/sda"{print $4}'
Portably:
df -P /dev/sda1 | awk 'NR==2 {print $4}'
The -P option ensures that df will print output in the expected format, and will in particular not break the line after the device name even if it's long. Passing the device name as an argument to df removes any danger from parsing, such as getting information for /dev/sda10 when you're querying /dev/sda1. df -P just prints two lines, the header line (which you ignore) and the one data line where you print the desired column.
There is a risk that df will display a device name containing spaces, for example if the volume is mounted by name and the name contain spaces, or for an NFS volume whose remote mount point contains spaces. In this case, there's no fully portable way to parse the output of df. If you're confident that df will display the exact device name you pass to it (this isn't always the case), you can strip it:
df -P -- "$device" | awk -vn=${#device} 'NR==2 {$0 = substr($0, n+1); print $3}'
Only in Linux
df --output=avail
You can use an awk
df | grep sda | awk '{print $4}'
You can query disk status with stat as well. To query free blocks on filesystem mounted at /:
stat -f -c '%f' /
To get the result in bytes instead of blocks, you can use shell's arithmetic:
echo $((`stat -f -c '%f*%S' /`))
Very similar answers to the ones shown, but if you don't know the name of filesystem and are just looking for the total available space on the partition.
df -P --total | grep 'total' | awk '{print $4}'

How to extract the first column from an output line?

When executing
sudo fdisk -l | tail -n 1
the result gives me
/dev/sdb1 * 8064 7669823 3830880 b W95 FAT32
So what I need is to extract just "/dev/sdb1/".
Not exactly just sdb1, whatever device that is listed last. What if I have two flash drives and I need the last one?
I've searching everywhere and I couldn't find how.
Thanks in advance.
sudo fdisk -l | tail -n 1 | awk '{print $1}'
will produce as
/dev/sdb1

bash script that computes used diskspace percentage for given partition

I have a bash script that computes used diskspace percentage for given partition:
df -k $devname | grep -v ^File | awk '{printf ("%i",$3*100 / $2); }
it doesn't work on a partition with long name because the name pushes the other columns to the next line, how do I fix this?
df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/VolGroup60-ROOT
2865493440 2222006740 497927968 82% /
tmpfs 30913808 0 30913808 0% /dev/shm
/dev/sda1 495844 103347 366897 22% /boot
Instead of parsing the entire "table" you could output the usage in percentage directly by using the --output parameter (see man 1 df for details):
$ df -k --output=pcent /dev/sda1
Use%
13%
That should be a lot easier to filter.
E.g. by creating an array with readarray in Bash 4:
$ readarray -t -s 1 percentage < <(df -k --output=pcent /dev/sda1)
$ echo "${percentage[0]// /}"
13%
Assigning the output of df to an array line by line:
$ percentage=($(df -k --output=pcent /dev/sda1))
$ echo "${percentage[1]}"
13%
The -P (portability) option for df use a output format compliant with posix and keeps everything in one line. You can also simplify the awk part using sel.

how to do this in bash script

in Linux, suppose mount command return this
/dev/sdc1 on /media/ELF (^-^)V type vfat
/dev/sdb1 on /media/PENDRIVE type vfat
all I want to do is get all mount point of my usb disk.
I did that already, using combination of grep and sed I can get these:
/media/ELF (^-^)V
/media/PENDRIVE
the problem is, when I do for loop in bash, those text will become 3 part instead of 2 parts , I mean :
suppose I put the result of those text in LIST
for list in $LIST; do
echo $list
done;
the result of that for loop becomes
/media/ELF
(^-^)V
/media/PENDRIVE
how to handle this issue? or are there any easier ways to get mount point of my usb disk?
Thanks
If you've already extracted the mountpoint paths and the only issue is to process them in a loop:
while read -r mountpoint; do
echo "[$mountpoint]"
done < <(mount | grep /media | grep uhelper=udisks | sed -e 's/\/dev\/.*on //g' -e 's/ type .*//g')

Bash: Selected Part in BOLD font in bash shell

Is there any way to grep some text from large file and mark that in BOLD letters in Linux BASH shell ?
Like
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 15G 11G 3.3G 76% /
tmpfs 7.9G 0 7.9G 0% /dev/shm
/dev/sda3 51G 45G 3.8G 93% /home
/dev/sdc1 917G 359G 512G 42% /data
I have above output and I want whenever system mails me about this df output the /data line should be in bold letters.
Using ANSI escape sequence you can do this (though this is terminal dependent):
echo -e "\033[1m$(grep '/data' file)\033[0m"
Will produce:
/dev/sdc1 917G 359G 512G 42% /data
Bash doesn't really have bold (it does have bright which is effectively equivilent). You could use sed to insert the bash control codes, but if you are less concerned with the exact colour choice, you can use
grep --color -E "text match pattern|" mylargefile
To get grep to do the highlighting. (see Colorized grep -- viewing the entire file with highlighted matches for alternatives and discussion)

Resources