Reputation: 773
How to search for a string from/after certain line in text file using bash script?
E.g. I want to search for first occurrence of "version:"
string but not at start of file but at line no. say 35 which contains text *-disk:0
so that I would get product name of disk-0 only and nothing else.
My current approach is as follows where line_no
was line no. of the line where disk:0
is present. But sometimes there is vendor name also present in-between the disk:0
and version
. At that time, this logic fails.
ver_line_no=$(echo $(( line_no + 6 )))
ver_line_text=`sed -n ${ver_line_no}p $1`
check_if_present=`echo $fver_line_text | grep "version:"`
Background:
I am trying to parse output of lshw
commmand.
*-disk:0
description: ATA Disk
product: SAMSUNG
physical id: 0
bus info: scsi@z:y:z:0
logical name: /dev/sda
version: abc
serial: pqr
size: 2048GiB
capabilities: axy, pqr
configuration: pqr, abc, ghj
*-disk:1
description: ATA Disk
product: TOSHIBA
physical id: 0
bus info: scsi@p:q:z:0
logical name: /dev/sdb
version: nmh
serial: pqasd
size: 2048GiB
capabilities: axy, pqr
configuration: pqr, abc, ghj
This is the sample information. I want to print information in tabular format using bash script.
Upvotes: 0
Views: 460
Reputation: 2893
A general solution using awk (assuming that every disk has a version).
File 'find_disk_version.awk'
/disk:/ {
disk_found="true"
disk_name=$1
}
/version:/ {
if (disk_found) {
print disk_name" "$2
disk_found=""
}
}
Test file 'test':
Something_else
version: ver_something_else
serial: blabla
configuration: foo, bar
*-disk:0
description: ATA Disk
version: ver.0
serial: pqr
*-disk:1
version: ver1
serial: pqasd
configuration: pqr, abc, ghj
Something_else_again
version: ver_somethingelse_again
serial: foobar
configuration: bar, foo
*-disk:2
version: ver2
serial: pqasd
configuration: pqr, abc, ghj
Output:
$ cat test | awk -f find_disk_version.awk
*-disk:0 ver.0
*-disk:1 ver1
*-disk:2 ver2
Instead of 'cat test' can be your command 'lshw'
P.S. the script will not work if there is a disk without version.
Upvotes: 0
Reputation: 7445
sed
solution:
If you want to search for first occurrence after given line number (e.g. 10
).
l=10
lshw | sed -n "${l},$ {/version/{p;q}}"
If you want to search for first occurrence after given line content (e.g. *-disk:0
)
lshw | sed -n '/*-disk:0/,${/version/{p;q}}'
Upvotes: 1
Reputation: 142005
You need to print all lines up the end. The $
represents the end in sed
.
sed -p '6,$p'
Will print lines from 6th line to the end. Be aware of quoting, so that $
doesn't get expanded.
You want:
ver_line_no=$(( line_no + 6 ))
ver_line_text=$(sed -n "${ver_line_no}"',$p' "$1")
check_if_present=$(echo "$fver_line_text" | grep "version:")
Notes:
$( ...)
command substitution instead.echo $(( .. ))
is just repeating yourself. Just $(( ... ))
.sed
you can use cut -d $'\n' -f6-
. Upvotes: 0
Reputation: 6198
You should be able to cut out the block you want with sed
, then use grep
:
sudo lshw | sed -n '/\*-disk:0/,/\s*\*/p' | grep 'version:'
The sed
command does not print any lines (-n
), then finds the block between *-disk:0
and the next *
and prints only that (p
).
Upvotes: 1
Reputation: 786289
You may use this awk
that searches for *-disk:0
in a file to toggle a flag to true:
awk -F: '$1 ~ /\*-disk$/{p = ($2 == 0)} p && /^[[:blank:]]*version:/' file
version: abc
Upvotes: 0