[英]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
(...)
) 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.