gee*_*eek 3 linux awk text-processing regular-expression
我有一个由 strace 生成的大文本文件,其中简要包含:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
42.93 3.095527 247 12512 unshare
19.64 1.416000 2975 476 access
13.65 0.984000 3046 323 lstat
12.09 0.871552 389 2239 330 futex
11.47 0.827229 77 10680 epoll_wait
0.08 0.005779 66 88 fadvise64
0.06 0.004253 4 1043 193 read
0.06 0.004000 3 1529 3 lstat
0.00 0.000344 0 2254 1761 stat
[...]
0.00 0.000000 0 1 fallocate
0.00 0.000000 0 24 access
0.00 0.000000 0 1 open
Run Code Online (Sandbox Code Playgroud)
不包括第一个标题行,我想从每一行获取最后一个字段,对应于系统调用列。这些包括:
这是我尝试过的
tail -n -13 seccomp | awk '{print $5}',它能够忽略第一行,但由于我的搜索没有细化,某些包含错误行的行被忽略。
我如何实现这个?
Rud*_*diC 13
或者像这样:
\nawk 'NR>2 {print $NF}' seccomp\nunshare\naccess\n.\n.\n.\nRun Code Online (Sandbox Code Playgroud)\n对于第二行之后的行,打印该行的最后一个字段。NF保存字段数,$NF“扩展”到最后一个字段的内容\xc2\xb9。
\xc2\xb9 或整个记录(如果不包含任何字段)(仅由空格组成FS,默认值为 字段分隔符)。
小智 10
您可以轻松地使用grep选项-o(缩写形式--only-matching)。
grep -o "\w*$" filename
Run Code Online (Sandbox Code Playgroud)
\w匹配任何单词字符(字母数字和下划线)\w*匹配多个(包括零个)单词字符\w*$匹配行尾的多个单词字符要跳过标题,请tail -n +3按照其他人的建议使用:
tail -n +3 filename | grep -o "\w*$"
Run Code Online (Sandbox Code Playgroud)
输出是这样的:
unshare
access
lstat
futex
epoll_wait
fadvise64
read
lstat
stat
fallocate
access
open
Run Code Online (Sandbox Code Playgroud)
有了sed它就简单了
sed '1,2d;s/.* //'
Run Code Online (Sandbox Code Playgroud)
1,2d意思是d删除第一行到第二行,替换tails删除最后一个空格之前的所有内容,因此您不需要计算列数据我所知,系统调用不能包含任何空格,所以这应该可行。否则,您可以依赖从第 61 个字符开始的名称,删除前 60 个字符:
sed '1,2d;s/.\{60\}//'
Run Code Online (Sandbox Code Playgroud)
打印一行中最后一个字段的标准习惯用法是
awk '{print $NF}'
Run Code Online (Sandbox Code Playgroud)
该NF变量会自动设置为该行的字段数,然后提取该字段。$
我想说,摆脱不需要的标题行的最简单、最安全的方法是使用egrep.
把这些放在一起我们有:
scs$ awk '{print $NF}' seccomp | egrep -v '^(--*|syscall)$'
Run Code Online (Sandbox Code Playgroud)
(这会错误地排除名为“syscall”的实际系统调用。想必这应该不是问题。)