繁体   English   中英

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

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

所以基本上我有一些这样的文字:

[ 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

我想要得到的是:

.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 

我试过这样的事情:

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

但问题是, [ 4]有一个空间..,这意味着在4-9行,我必须使用

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

无论如何在获取我想要的所有列时使用单个命令..?

你也可以尝试:

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

如果您想通过选择列宽来保持可读性:

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

您的文件也不是不可能将\\t (制表符)作为字段分隔符; 如果是这样,你可以尝试:

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

希望这可以帮助。

使用gnu awk您可以使用这种优雅的方式处理字段固定宽度的文本。 它还将保留格式。

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

如果你可以使用perl

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

在行动:

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

您可以使用-F添加字段分隔符选项:

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

作为字段分隔符传递的正则表达式负责在每行的开头处出现数值/空间歧义的可能性。

您可以在[ :]之后立即删除任何空格

sed 's_\[\s_[_'

尝试,

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

它会打印[1]

一个sed解决方案(GNU sed和FreeBSD / OS X sed ) - 给@Tiago有用的Perl解决方案的秘诀:

sed -E 's/^.*\] (.*)PROGBITS( +[^ ]+)( +[^ ]+)( +[^ ]+).*$/\1 \2 \3 \4/' file
  • 使用匹配行的正则表达式,捕获组( (...) )匹配感兴趣的数据(包括前面的空格),然后用仅感兴趣的数据替换行 - \\1指的是第一次捕获小组的比赛, \\2到2,......

请注意,它可以以符合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