[SOLVED] grep upto specific keyword from a file under Redhat 6
Linux - ServerThis forum is for the discussion of Linux Software used in a server related context.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
grep upto specific keyword from a file under Redhat 6
I am trying to write a script for checking the SAN path status in Linux nodes under the multipath. For checking the multipath status, I am sorting out the mpath names and looping the multipath -ll output with the mpath name to process the output. By this I'm able to check the status of all the LUNs. But problem is if the server has many LUNs, it is taking long time to execute the script because of looping the multipath -ll command multiple times. So I was thinking if I can redirect the multipath -ll output to a file and then process the mpath output instead of looping the multipath -ll output it will speed up the execution time. I can grep out information for the specific mpath device from that file with the -A option in grep command if the no of following lines are same for all the LUNs. But here problem is some mpath may have 2 underline devices or 4 or 8 devices. So following lines count will be different for each mpath device. So only if I can grep until the next occurrence of mpath keyword, I can accomplish my purpose. So if anyone can help me with how to do (may be via grep or sed or awk or any other method) so I will be very grateful to him.
So from the above output of multipath -ll command how can I grep or print only the info about a specific mpath device e.g mpathi (you can see the no of lines is different for each mpath device).
grep won't fit there as you point out because of the variable number of lines.
With awk it is easy and can be done in three steps.
Code:
awk '/^mpathj/ && !flag { print; flag++; next }; /^mpath/ && flag { exit }; flag { print } ;
That represents three if-then conditions in serial, separated by semicolons. 'print' is short for 'print $0' There may be a sounder or more elegant way to do it.
That will work for either the pattern "mpathj" or "mpathi" or similar. You'll have to adapt it yourself to fit it into your actual workflow.
flag is a variable. undefined it starts out as equivalent to 0. Using ++ increments it, setting it to 1.
/^mpathj/ looks for "mpathj" at the start of the input line. Actually it's the caret ^ that indicates the beginning of the line. Without it, the pattern would match "mpathj" anywhere on the line.
awk statements are separated by semicolons. By default they are if-then clauses, with the action being contained in the braces. So in pseudo-code what you are seeing above is this:
Code:
while ( $0 = readnewline ) {
if ( $0 =~ /^mpathj/ ) then
{
print $0; # print the current line
$flag++; # increment the flag
next; # skip the rest of the stuff below and start again and read the next line
}
if ( $0 =~ /^mpath/ AND $flag != 0 ) then
{
exit; # quit the awk program now
}
if ( $flag != 0 ) then
{
print $0; # print the current line
}
}
"print" by itself is short for "print $0", which means the whole line
Try taking a look at the manual page for awk now, some parts should look familiar.
Thanks Turbocapitalist. I will have a look in the man page and will try to understand the code. If I have any doubt I will come back and will try to clear that.
Thanks syg00 & HMW for your kind response.
I was trying and the code worked. Now what I am trying, is creating for loop with the mpathX putting them into a variable and trying to use the variable in the code provided by you. But some how the sed command is not reading the variable properly and showing nothing as output. So can you please help how to use the mpath as variable in the sed command provided by you?
Use double-quotes around the sed code rather than single. You don't need the internal double-quotes you added.
I don't think that will do what you want, but I'll leave you to debug your changes.
That eliminates cat, which is often not needed, as well as a redundant grep. The awk language includes some pattern matching like grep.
About about the quotes, the double and single quotes work differently. The single quotes preserve the literal value of what's between them. The double quotes allow some processing. Compare:
Code:
echo "Home is $HOME for $USER."
echo "Today is $(date +%F)."
echo 'Home is $HOME for $USER.'
echo 'Today is $(date +%F).'
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.