简体   繁体   中英

Bash. awk last column with possible spaces

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?

如果您确定您关心的数据永远不会有多个空格的运行,那么请将其用作字段分隔符。

awk -F '\t| {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 (eg 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.

你可以尝试这个awk:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM