Pregunta

I know that awk can be used to print only certain words from the output.For example

dpkg -l|awk '{print $2}'

would print 2nd word from the output of dpkg -l.

What I want to do is, print every word after a given word.My command looks like this

awk '{printf "%-40s %s\n", $1, $n}'

Rather than printing all the words with $n or $0, I would like to print every word that comes after, say 5th character.

How can I do this?

EDIT: my complete command is

bind -P|grep "can be found"|sort|awk '{printf "%-40s %s\n", $1, $n}'

This gives output like

abort                                    abort can be found on "\C-g", "\C-x\C-g", "\e\C-g".
accept-line                              accept-line can be found on "\C-j", "\C-m".
backward-char                            backward-char can be found on "\C-b", "\eOD", "\e[D".
backward-delete-char                     backward-delete-char can be found on "\C-h", "\C-?".

character-search-backward                character-search-backward can be found on "\e\C-]".
character-search                         character-search can be found on "\C-]".
clear-screen                             clear-screen can be found on "\C-l".

and many more lines. The "abort can be found in" and similar lines are irrelevant, I don't want them, but I want everything that comes after those 5 characters.

So the output should look like

abort                                    "\C-g", "\C-x\C-g", "\e\C-g".
accept-line                              "\C-j", "\C-m".
backward-char                            "\C-b", "\eOD", "\e[D".
backward-delete-char                     "\C-h", "\C-?".

How can do this with awk or any other command? I need to keep the columnar output.

¿Fue útil?

Solución

Try below:

 many commands | awk '{for(i=6;i<=NF;i++){printf "%s\n", $i}}'

Will print everything from field 6 onwards, if you dont want a newline seperating each word use below:

many commands | awk '{for(i=6;i<=NF;i++){printf "%s ", $i}}'

EDIT:

for your complete question use below:

 bind -P|grep "can be found"|sort | awk '{printf "%-40s", $1} {for(i=6;i<=NF;i++){printf "%s ", $i}{printf"\n"}}'

Gives output:

abort                                   "\C-g", "\C-x\C-g", "\e\C-g".
accept-line                             "\C-j", "\C-m".
backward-char                           "\C-b", "\eOD", "\e[D".
backward-delete-char                    "\C-h", "\C-?".
backward-kill-line                      "\C-x\C-?".
etc...

Otros consejos

use a better tool in this case like perl:

perl -lne 'print $1 if(/\b(myword .*)/)'

Not exactly sure what you are looking for. But this removes the first 5 words in the line:

awk '{for(i=6;i<=NF;i++){printf $i" "}print ""}'

Tested

If you need to explicitly use AWK you can try the following:

awk '{ if( match($0,"^.{5}[^[:space:]]*[[:space:]]([^[:space:]]+)(:?$|[[:space:]])", arr) ) {print arr[1]}}'

The match function ensures that there are at least 5 characters (blank and alphanumeric) before it starts capturing a word. If the next element after the fifth character is the middle of a word, it just ignores it and goes to the next full word and captures it. The first position in arr corresponds to the captured element in the regular expression, which is the first complete word after the fifth character.

Save the first field. As a condition/pattern, attempt to substitute an empty string for ".*can be found on ". If a substitution occurs, print the saved first field and whatever's left of $0.

bind -P | awk '{ first = $1 } sub(/.*can be found on /, "") { printf "%-40s%s\n", first, $0 }

In your original version:

bind -P|grep "can be found"|sort|awk '{printf "%-40s %s\n", $1, $n}' The n in $n evaluates to 0 so awk prints both the first word and the entire record.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top