Reputation: 53
This site have helped me a lot in the past but signed up only now as I couldn't find an exact answer for what am trying now. I hope you would be able to help.
I'm trying to extract or cut the values under a string in a file. My file looks like:
Xmqqstab v1.0 - Developed by Oliver Fisse (ISSW)
****
**** Tuesday, April 26, 2016 10:49:21 AM BST ****
****
UNIX
Report for queue(s): 'Q1' on queue manager 'QMGR'...
CQD PQF MxQD OIC OUC UNC LGETDATE LGETTIME LPUTDATE LPUTTIME QOM G P Local Queue Name
----------------------------------------------------------------------------------------------------------------------------------------------------
5 0.10% 5000 0 0 0 2016-04-26 10.48.46 2016-04-26 10.49.01 26s E E - Q1
1 queue(s) matching.
The file actually gives MQ queue statistics and am trying to get the values under say, CQD=5
(this could be any digit number), LGETTIME=10.48.46
.
I could get the line with the values using: grep -A3 'CQD' file.txt | sed -n '3p'
. And from the line I will have to cut the values by column but I thought it wont be accurate to do so as the digits could vary like 5 in this case could be a four digit number in which case the column numbers would change.
I hope am clear with the question.
Would appreciate any help.
Thanks.
Upvotes: 4
Views: 182
Reputation: 14651
The simplest solution would be just replacing your multiple spaces with a delimiter of your choice, and then cut
would work reliably, just as you planned it first:
grep -A3 'CQD' file.txt | sed -n '3p' | sed 's/ */_/g' | cut -f2 -d'_'
This is the part that replaces multiple spaces with underscore:
sed 's/ */_/g'
Upvotes: 0
Reputation: 10324
Assuming the data you're interested in is the 1st line that starts with a digit:
read my_CQD my_LGETDATE <<< $(awk '$1 ~ /^[0-9]/ {print $1, $8; exit}' file.txt)
Explanation:
The awk
program watches for a line whose first field begins with a digit. It then prints the 1st and 8th fields separated by a space then quits. Bash reads these two values into $my_CQD
and $my_LGETDATE
.
Output:
echo -e "\$my_CQD: $my_CQD\n\$my_LGETDATE: $my_LGETDATE"
$my_CQD: 5
$my_LGETDATE: 10.48.46
Upvotes: 0
Reputation: 74685
You could go for something like this:
awk '/CQD/ { for (i = 1; i <= NF; ++i) if ($i == "CQD") col = i } col && $col == 5' file
On the line matching the field name of interest, loop through each field to find the column that contains it. When col
has been set and the value in the column matches the one you want, print the line (the default action).
You could pass the heading and value as parameters to the script if you wanted:
awk -v heading=CQD -v value=5 '$0 ~ heading {
for (i = 1; i <= NF; ++i) if ($i == heading) col = i
} col && $col == value' file
Using either of these approaches, the output is the line:
5 0.10% 5000 0 0 0 2016-04-26 10.48.46 2016-04-26 10.49.01 26s E E - Q1
...which I'm assuming is what you're looking for!
Upvotes: 3
Reputation: 14949
With sed
:
sed -rn '/CQD.*LGETTIME/{n;n; s/^ *([^ ]* *)([^ ]* *){6}([^ ]*).*/\1\3/p}'
Output:
$ sed -rn '/CQD.*LGETTIME/{n;n; s/^ *([^ ]* *)([^ ]* *){6}([^ ]*).*/\1\3/p}' file
5 10.48.46
Upvotes: 0