我使用 awk 来解析日志;我从未见过这样的事情:我有六个包含多行的文件;我想要包含“100”的那些,并选择要打印的列
me:~/tmp> grep 100 *.dl.tst
Run Code Online (Sandbox Code Playgroud)
输出我期望的:
100 139M 100 139M 0 0 6376k 0 0:00:22 0:00:22 --:--:-- 6539k
100 139M 100 139M 0 0 6677k 0 0:00:21 0:00:21 --:--:-- 6579k
100 139M 100 139M 0 0 6022k 0 0:00:23 0:00:23 --:--:-- 6093k
100 139M 100 139M 0 0 13.9M 0 0:00:10 0:00:10 --:--:-- 14.3M
100 139M 100 139M 0 0 14.3M 0 0:00:09 0:00:09 --:--:-- 14.7M
100 139M 100 139M 0 0 13.2M 0 0:00:10 0:00:10 --:--:-- 13.3M
Run Code Online (Sandbox Code Playgroud)
就像:
me:~/tmp> grep 100 *.dl.tst|awk '{print$0}'
100 139M 100 139M 0 0 6376k 0 0:00:22 0:00:22 --:--:-- 6539k
100 139M 100 139M 0 0 6677k 0 0:00:21 0:00:21 --:--:-- 6579k
100 139M 100 139M 0 0 6022k 0 0:00:23 0:00:23 --:--:-- 6093k
100 139M 100 139M 0 0 13.9M 0 0:00:10 0:00:10 --:--:-- 14.3M
100 139M 100 139M 0 0 14.3M 0 0:00:09 0:00:09 --:--:-- 14.7M
100 139M 100 139M 0 0 13.2M 0 0:00:10 0:00:10 --:--:-- 13.3M
Run Code Online (Sandbox Code Playgroud)
那么为什么会$1变成文件名:
me:~/tmp> grep 100 *.dl.tst|awk '{print$1}'
shpr002.20201124_141036.dl.tst:
shpr003.20201124_141036.dl.tst:
shpr004.20201124_141036.dl.tst:
hipr002.20201124_141036.dl.tst:
hipr003.20201124_141036.dl.tst:
hipr004.20201124_141036.dl.tst:
Run Code Online (Sandbox Code Playgroud)
并且$2:
me:~/tmp> grep 100 *.dl.tst|awk '{print$2}'
0
0
0
0
0
0
Run Code Online (Sandbox Code Playgroud)
我注销并重新登录,以防我的 shell (bash) 搞砸了;没有变化......我做错了什么?
输出grep 100 *.dl.tst | awk '{print$1}' | head -n1 | od -c
(一些字母字符已被替换x;上面的列表已被编辑/混淆)
0000000 x s h p r 0 0 2 x x x . x x x .
0000020 x x x x . c o m . 2 0 2 0 - 1 1
0000040 - 2 4 _ 1 4 1 0 3 6 . d l . t s
0000060 t : \r \n
0000064
Run Code Online (Sandbox Code Playgroud)
Ste*_*itt 16
这些文件包含curl下载文件的输出,并curl在下载过程中通过输出回车(通常表示为\r,用于在许多上下文中产生它的转义)更新其进度信息,这会导致光标返回到线。
当您运行 时grep 100 *.dl.tst,输出的每一行都以文件名开头,但随后是多个更新,这些更新将光标返回到行的开头,因此您看不到文件名——它被后续输出覆盖。更详细地说,输出看起来像
shpr002.20201124_141036.dl.tst:
Run Code Online (Sandbox Code Playgroud)
后面跟着一个回车,后面跟着第一个进度输出curl,
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
Run Code Online (Sandbox Code Playgroud)
然后是回车等,直到百分比达到100。因为所有这些只是由回车分隔,而不是换行符,所以它算作一行,并grep与整个行匹配。
同样的效果解释了 的输出grep 100 *.dl.tst|awk '{print$0}'。
当您要求 AWK 输出时$1,它输出第一个字段,现在您可以看到它:它包含文件名、冒号、回车符,仅此而已 -curl输出的开头然后以空格开头(到为百分比计数留出空间),这是一个字段分隔符。当您要求它 output 时$2,它会输出第二个字段,即第一个百分比计数0:
shpr002.20201124_141036.dl.tst:\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
<-- Field 1 --> ! ! ! ! ...
$2 $3 $4 $5 ...
Run Code Online (Sandbox Code Playgroud)