问题
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