grep to select lines with M in last word
I have a large file in which each line has three or more blank-delimited words. I'd like to code a grep to keep only those lines which have the letter M in the last word. If it's any help, the M (if present) will be the first character in the last word.
|
Something like this:
Code:
awk '{ if ($NF ~ /M/) print $0 }' input |
Or grep could be:
Code:
egrep 'M[^ ]*$' file |
Quote:
|
Not better .. just different .. I am normally the awk proponent but as you beat me to it I was happy to give an alternative :)
|
There is at least one case where egrep fails.
Quote:
Code:
~$ echo -e "Fable Mabel\nHairy Mary \nMary Martian" Many human generated text files contain random, unnecessary space characters. They tend to accumulate in places where they go unnoticed, such as adjacent to other whitespace. It matters even more when processing the output of other programs. For one example, ifconfig likes to add space characters before newline characters. Code:
~$ ifconfig | hd | grep '20 20 0a' Code:
~$ echo -e "Fable Mabel\nHairy Mary \nMary Martian" | awk '$NF~"M"' |
Quote:
Please give a bit of explanation, and then I will mark this puppy as solved. My newbie reading is this ... The M is the character which governs selection or rejection. The [^ ] says "apply this logic to strings starting with blank." The * says "apply this logic to all such strings in each line." The $ says "the last string in each line is the only important one." Please revise this narrative to make it more correct and instructive. Thank you! |
Quote:
As pointed out, it would not match if there happen to be any spaces between the last word and the end of the line. To catch that, you need to make a small modification. Code:
egrep 'M[^[:space:]]*[[:space:]]*$' I also replaced the simple space with the [:space:] character class here, meaning any kind of whitespace, so tabs would be matched in addition to regular spaces, although it's likely not necessary for your situation. |
Quote:
|
Quote:
Code:
awk '$NF~"M"' |
My mother always told me not to stick my nose where it doesn't belong, but I don't listen to my mother very often.
Quote:
Second, it wasn't David the H's command originally, but a follow-on to grail's. Quote:
How is it better? To quote the original post: Quote:
So I assume the next time you ask someone to pass the salt you'll be happy when they give you pepper. Relax... seriously. Don't get so defensive. |
Code:
grep 'M[^ ]*$' filename Quote:
|
Quote:
As for the rest of your message, it seems to be an unwarranted attempt to inject personal animosity into an otherwise friendly discussion. I see that you are ranked senior member, so I'm guessing you didn't get to be one <moderated>. I'll just say your message reads like a personal attack, although I don't claim it is. Quote:
:scratch: Anyway, this thread isn't a good place for you and I to make friends. Feel free to PM me if you don't want to change the topic of the OP. |
This thread is going a bit off-topic! Please, keep discussion fair and reasonable. No need to be pedantic, disrespectful or - even worse - offensive towards other members. The OP already gained proper answers and hopefully learned something useful about regular expressions. Nuff' said!
|
I'll unsubscribe from this thread immediately after this response. It's my hope that this won't be taken as offensive in any way--merely an explanation for my original response.
The original response from Telengard that I quoted (#10) accused the egrep command from David the H. (which was a modified version of grail's original command that addressed Telengard's comments about end-of-line spaces) as being worse than Telengard's own awk command--and did so by saying the egrep used a "whopping" number of characters. It's clear that "whopping" was not used in a complimentary way. In my term here at LQ, I've participated in a number of threads. I have offered a number of solutions to problems. I cannot recall any instance where I accused another member's proposed solution as being worse or inferior to my own. I have pointed out technical problems with solutions posted, but I have never complained when a subsequent version of the command is posted to address those concerns. I simply, quietly let the OP decide which solution they want to use. To me, such a complaint is an attack on the proposed solution in an effort to defend some other solution as "better." To me, that is unwarranted defensive behavior. We're all here to contribute and it's not about the "best" solution or the most "efficient" unless that's what the OP asks for. |
It's generally good to give a variety of solutions, even if only for educational purposes, which is the main reason I posted what I did. I agree that in this particular case awk may indeed be the more efficient solution, but I was more concerned with demonstrating how regular expressions work than in what works "best" here. And it may help some reader down the line working on something similar; someone who doesn't have access to or understand how to use awk, for example, or who needs a regex solution specifically.
|
Dark Helmet, your arguments are reasonable and well phrased. Evidently, the slightly sarcastic tone you used in your previous post has not been well accepted by Telengard and he overreacted to criticism. Now that your reasons are more clear, we hope that the does not lead to anything discussion will terminate and that you will shake your hands.
|
David the H., thank you for clarifying.
|
what about using perl?
Quote:
|
Quote:
Code:
awk '$NF~/^M/' |
Quote:
Code:
'$NF ~ "M"' Code:
'$NF ~ /^M/' Please note the thread has been marked as solved by the OP, therefore let's add further information only if they are really valuable and give an actual improvement to the technical discussion. Thanks. |
All times are GMT -5. The time now is 05:26 AM. |