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