简体   繁体   English

如何使用`awk`来grep某些像这样的列?

[英]How to use `awk` to grep certain columns like these?

So basically I have some text like this: 所以基本上我有一些这样的文字:

[ 4] .init             PROGBITS        080481c0 0001c0 00002e 00  AX  0   0  4
[ 5] .plt              PROGBITS        080481f0 0001f0 000110 00  AX  0   0 16
[ 6] .text             PROGBITS        08048300 000300 07c95c 00  AX  0   0 16
[ 7] __libc_thread_fre PROGBITS        080c4c60 07cc60 000076 00  AX  0   0 16
[ 8] __libc_freeres_fn PROGBITS        080c4ce0 07cce0 000b2f 00  AX  0   0 16
[ 9] .fini             PROGBITS        080c5810 07d810 00001a 00  AX  0   0  4
[10] .rodata           PROGBITS        080c5840 07d840 019774 00   A  0   0 32
[11] __libc_thread_sub PROGBITS        080defb4 096fb4 000004 00   A  0   0  4
[12] __libc_subfreeres PROGBITS        080defb8 096fb8 00002c 00   A  0   0  4
[13] __libc_atexit     PROGBITS        080defe4 096fe4 000004 00   A  0   0  4

What I am trying to get is this: 我想要得到的是:

.init                    080481c0 0001c0 00002e 
.plt                     080481f0 0001f0 000110 
.text                    08048300 000300 07c95c 
__libc_thread_fre        080c4c60 07cc60 000076 
__libc_freeres_fn        080c4ce0 07cce0 000b2f  
.fini                    080c5810 07d810 00001a 
.rodata                  080c5840 07d840 019774 
__libc_thread_sub        080defb4 096fb4 000004 
__libc_subfreeres        080defb8 096fb8 00002c  
__libc_atexit            080defe4 096fe4 000004 

I tried something like this: 我试过这样的事情:

 awk '/PROGBITS/ {print $2,$4,$5,$6} '

but the problem is that, there is a space inside [ 4] .. , which means in the 4-9 line, I have to use 但问题是, [ 4]有一个空间..,这意味着在4-9行,我必须使用

awk '/PROGBITS/ {print $3,$5,$6,$7} '

Is there anyway to use a single command while getting all the columns I want..? 无论如何在获取我想要的所有列时使用单个命令..?

You can also try: 你也可以尝试:

awk '/PROGBITS/{print $(NF-9),$(NF-7),$(NF-6),$(NF-5)}' file

If you want to keep something readable, by choosing the columns width: 如果您想通过选择列宽来保持可读性:

awk '/PROGBITS/{printf "%-18s %-10s %-10s %-10s\n", $(NF-9),$(NF-7),$(NF-6),$(NF-5)}' file

It is also not impossible that your file has \\t (tabs) as field separators; 您的文件也不是不可能将\\t (制表符)作为字段分隔符; if so, you may try: 如果是这样,你可以尝试:

awk -F"\t" '{print $2,$4,$5,$6}' file

Hope this helps. 希望这可以帮助。

With gnu awk you have this elegant way to handle text with fixed width on fields. 使用gnu awk您可以使用这种优雅的方式处理字段固定宽度的文本。 It will also keep the formatting. 它还将保留格式。

awk -v FIELDWIDTHS="5 18 16 8 7 8" '{print $2,$4,$5,$6}' file
.init              080481c0  0001c0  00002e
.plt               080481f0  0001f0  000110
.text              08048300  000300  07c95c
__libc_thread_fre  080c4c60  07cc60  000076
__libc_freeres_fn  080c4ce0  07cce0  000b2f
.fini              080c5810  07d810  00001a
.rodata            080c5840  07d840  019774
__libc_thread_sub  080defb4  096fb4  000004
__libc_subfreeres  080defb8  096fb8  00002c
__libc_atexit      080defe4  096fe4  000004

如果您只需要按指定的方式提取列cut将执行以下操作

cut -c 6-22 -c 32-62 file

If you can use perl : 如果你可以使用perl

perl -lne '/\] \K(.*)PROGBITS\s+(\w+)\s+(\w+)\s+(\w+)/ && print "$1 $2 $3 $4" '

In action: 在行动:

perl -lne '/\] \K(.*)PROGBITS\s+(\w+)\s+(\w+)\s+(\w+)/ && print "$1 $2 $3 $4" ' file
.init              080481c0 0001c0 00002e
.plt               080481f0 0001f0 000110
.text              08048300 000300 07c95c
__libc_thread_fre  080c4c60 07cc60 000076
__libc_freeres_fn  080c4ce0 07cce0 000b2f
.fini              080c5810 07d810 00001a
.rodata            080c5840 07d840 019774
__libc_thread_sub  080defb4 096fb4 000004
__libc_subfreeres  080defb8 096fb8 00002c
__libc_atexit      080defe4 096fe4 000004

You can add a field-separator option with -F : 您可以使用-F添加字段分隔符选项:

awk -F'^\\\\[ *[0-9]+\\\\] | +' '{printf "%-24s %-8s %-6s %-6s\\n", $2, $4, $5, $6}' file

The regular expression passed as the field-separator takes care of the possibility of numerical/spacial ambiguity in the beginning of each line. 作为字段分隔符传递的正则表达式负责在每行的开头处出现数值/空间歧义的可能性。

You can simply remove any whitespace right after the [ : 您可以在[ :]之后立即删除任何空格

sed 's_\[\s_[_'

Try, 尝试,

echo '[ 1]' | sed 's_\[\s_[_'

It'll print [1] . 它会打印[1]

A sed solution (GNU sed and FreeBSD/OS X sed ) - tip of the hat to @Tiago's helpful Perl solution : 一个sed解决方案(GNU sed和FreeBSD / OS X sed ) - 给@Tiago有用的Perl解决方案的秘诀:

sed -E 's/^.*\] (.*)PROGBITS( +[^ ]+)( +[^ ]+)( +[^ ]+).*$/\1 \2 \3 \4/' file
  • Uses a regular expression that matches the entire line, with capture groups ( (...) ) matching the data of interest (including preceding whitespace), and then replacing the line with only the data of interest - \\1 refers to the 1st capture group's match, \\2 to the 2nd, ... 使用匹配行的正则表达式,捕获组( (...) )匹配感兴趣的数据(包括前面的空格),然后用仅感兴趣的数据替换行 - \\1指的是第一次捕获小组的比赛, \\2到2,......

Note that it can be done in a POSIX-compliant manner, but it gets ugly: 请注意,它可以以符合POSIX的方式完成,但它变得丑陋:

sed 's/^.*\] \(.*\)PROGBITS\( \{1,\}[^ ]\{1,\}\)\( \{1,\}[^ ]\{1,\}\)\( \{1,\}[^ ]\{1,\}\).*$/\1 \2 \3 \4/' file

尝试这个:

awk '/PROGBITS/ {if (NF==12) print $3,$5,$6,$7; else print $2,$4,$5,$6}'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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