How to print a series of words using awk?

微笑、不失礼 提交于 2020-02-21 13:49:42

问题


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.


回答1:


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...



回答2:


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




回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/22929600/how-to-print-a-series-of-words-using-awk

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!