3

I have a dynamic output. Like this sometimes:

F8:XX:94:XX:C2:XX 1 39% No ANY_NAME A2:XX:34:XX:E8:XX 6 42% Yes ANY_OTHER_NAME D1:XX:78:XX:A1:XX 6 24% No MORESTUFF 

Or like this other times:

F8:XX:94:XX:C2:XX 1 433 39% No ANY NAME A2:XX:34:XX:E8:XX 6 232 42% No ANY_OTHER_NAME D1:XX:78:XX:A1:XX 6 112 22% Yes MORE STUFF 

As you can see the last column is what I want but it can contain spaces or not and the number of columns is dynamic.

I need to capture the value of the last column always in case of having no spaces or having multiple spaces. Sometimes, the column number is dynamic too but the data I want is always in last place having spaces or not. The column before this data it's always a "Yes" or "No" (not sure if this can help).

Is there a way to do it with awk? This is what I have actually:

myvar=$(echo "${line}" | awk '{print $NF}') 

But with this is taking just the last part after a space, not the complete data. So this is working only if the data has no spaces.

What I want is to get always the last data complete with its spaces in case of containing them. Any help?

3
  • Is the column separator a tabulation or multiple spaces? In the second case, can you say that there will always be at least two spaces between columns, and at most one consecutive space in the last column's value? Commented Jul 29, 2018 at 17:52
  • can be both, spaces or tabs, it depends. Commented Jul 29, 2018 at 17:53
  • That's some badly formatted data ! Ignacio's answer should be fine though Commented Jul 29, 2018 at 17:56

3 Answers 3

5

If you're sure that the data you care about can never have a run of more than one space then use that as your field separator instead.

awk -F '\t| {2,}' ... 
Sign up to request clarification or add additional context in comments.

2 Comments

I'm testing it. It works for normal cases... but if the name has double space, for example "ANY[space][space]NAME" is not working. It could happen. Anyway, with your solution for now, is better than what I have.
I'll check your solution too. if is better i'll change my accepted answer, why not. Is known that with this solution a double space screw up the stuff. Upvoting anyway for all your contribution. thanks.
2

With GNU awk for \s and \S shorthand:

$ awk '{sub(/[^%]+%\s+\S+\s+/,"")}1' file ANY_NAME ANY_OTHER_NAME MORESTUFF ANY NAME ANY_OTHER_NAME MORE STUFF oh No lots of spaces 

With any awk:

$ awk '{sub(/[^%]+%[[:space:]]+[^[:space:]]+[[:space:]]+/,"")}1' file ANY_NAME ANY_OTHER_NAME MORESTUFF ANY NAME ANY_OTHER_NAME MORE STUFF oh No lots of spaces 

or with any sed that supports -E for EREs (e.g. GNU or OSX/BSD seds):

$ sed -E 's/[^%]+%[[:space:]]+[^[:space:]]+[[:space:]]+//' file ANY_NAME ANY_OTHER_NAME MORESTUFF ANY NAME ANY_OTHER_NAME MORE STUFF oh No lots of spaces 

The above was run on this input file:

$ cat file F8:XX:94:XX:C2:XX 1 39% No ANY_NAME A2:XX:34:XX:E8:XX 6 42% Yes ANY_OTHER_NAME D1:XX:78:XX:A1:XX 6 24% No MORESTUFF F8:XX:94:XX:C2:XX 1 433 39% No ANY NAME A2:XX:34:XX:E8:XX 6 232 42% No ANY_OTHER_NAME D1:XX:78:XX:A1:XX 6 112 22% Yes MORE STUFF D1:XX:78:XX:A1:XX 6 112 22% Yes oh No lots of spaces 

wrt your comments, here is the first script handling the input file contents being passed to it 1 line at a time from a pipe:

$ while IFS= read -r line; do echo "$line" | awk '{sub(/[^%]+%\s+\S+\s+/,"")}1' done < file ANY_NAME ANY_OTHER_NAME MORESTUFF ANY NAME ANY_OTHER_NAME MORE STUFF oh No lots of spaces 

All of the other scripts can be used exactly the same way.

10 Comments

checking your solution. it works if you create a file and it launchs it as you are doing, but what i need is an echo "line-stuff" | magic-awk-stuff and in that way is not working... I mean, an awk or sed command to be used after a pipe. It must be in this way. Any help? I really would like to use your solution which seems better to save double spacing.
Just do cat file | awk 'script' instead of awk 'script' file. Replace cat file with whatever your pipe is. If that's what you tried and it's not working then if you tell us in what way it's not working then there's a good chance we might be able to help you debug that issue.
But my program is doing it line by line... so I need echo "line-content" | awk-magic and it this way this is not working
You're going to have to be clearer about in what way it's "not working". Wrong output, no output, error message, core dump, what? There's absolutely nothing about any of the scripts in my answer that care if it's reading a file vs getting input from a pipe, or getting 1 million lines of input at a time or getting 1 line of input at a time. Edit your question to include a minimal, complete program that clearly demonstrates whatever problem you're having.
I need something to be used on each line to pass it using a pipe to the awk-magic-stuff . In my example of what I have i'm using the pipe. Anyway, thanks for your approach. For now the best answer for me is what is already marked as accepted answer. Sorry if it was not completely clear on the answer. I can change the accepted answer if you have a better approach. Thanks :)
|
1

You can try this awk :

awk '{sub(/.*(Yes|No)[[:blank:]]*/,"")}1' infile 

3 Comments

That will fail when MORESTUFF is I said No Thank You for example.
Yes, we can always find a way. Yours fail if it's a % before the 4th column.
Right but there's nothing in the question to indicate that can happen whereas the text at the end of each line is clearly just a placeholder for any text so there's no reason to think "No" or "Yes" cannot appear there. Obviously you can't cater to everything that might be completely different from what's in the posted sample input but when, as in this case, you see text in the provided example that indicates it can be any text then you should account for that when parsing it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.