意想不到的结果:grep来自变化的线

时间:2015-01-12 03:41:17

标签: shell grep echo mplayer

我写了一个bash命令来测试来自更改行的grep:

for i in $(seq 0 9); do echo -e -n "\r"$i;  sleep 0.1; done | grep 5

结果显示:

9

<小时/> 的更新

真正的问题如下:

mplayer在播放媒体文件时显示和刷新单行播放进度。样本结果是:

A:  17.2 (17.2) of 213.0 (03:33.0)  0.5%

而我正在努力改善这种进步并进入其他界限。我用了这个命令:

mplayer xxx.mp3 | grep ^A:

结果不包含预期的行。

<小时/> 更新2

mplayer xxx.mp3 | od -xda

所示:

0002140    4a5b    410d    203a    2020    2e31    2033    3028    2e31
          [   J  \r   A   :               1   .   3       (   0   1   .
        133 112 015 101 072 040 040 040 061 056 063 040 050 060 061 056
0002160    2932    6f20    2066    3132    2e33    2030    3028    3a33
          2   )       o   f       2   1   3   .   0       (   0   3   :
        062 051 040 157 146 040 062 061 063 056 060 040 050 060 063 072
0002200    3333    302e    2029    3020    342e    2025    5b1b    0d4a
          3   3   .   0   )           0   .   4   %     033   [   J  \r
        063 063 056 060 051 040 040 060 056 064 045 040 033 133 112 015
0002220    3a41    2020    3120    352e    2820    3130    342e    2029
          A   :               1   .   5       (   0   1   .   4   )    
        101 072 040 040 040 061 056 065 040 050 060 061 056 064 051 040
0002240    666f    3220    3331    302e    2820    3330    333a    2e33
          o   f       2   1   3   .   0       (   0   3   :   3   3   .
        157 146 040 062 061 063 056 060 040 050 060 063 072 063 063 056

mplayer xxx.mp3 | tr '\r' '\n'

显示

A:   0.2 (00.1) of 213.0 (03:33.0)  0.3% 
A:   0.3 (00.3) of 213.0 (03:33.0)  0.3% 
A:   0.5 (00.5) of 213.0 (03:33.0)  0.4% 
A:   0.6 (00.6) of 213.0 (03:33.0)  0.4% 
A:   0.8 (00.8) of 213.0 (03:33.0)  0.4% 
A:   1.0 (01.0) of 213.0 (03:33.0)  0.4%

虽然

mplayer xxx.mp3 | tr '\r' '\n' | grep ^A

显示空结果。

任何提示都将受到赞赏。

1 个答案:

答案 0 :(得分:1)

这是你在这里引起问题的“线”的定义。 -n表示所有数字都在行上输出,根据grep使用的定义(一系列字符,由\n终止字符):

\r1\r2\r3\r4\r5\r6\r7\r8\r9

如果通过类似十六进制转储的方式管道输出,您可以看到发生了什么:

$ for i in $(seq 0 9); do echo -e -n "\r"$i;  sleep 0.1; done | grep 5 | od -xcb
0000000    300d    310d    320d    330d    340d    350d    360d    370d
         \r   0  \r   1  \r   2  \r   3  \r   4  \r   5  \r   6  \r   7
        015 060 015 061 015 062 015 063 015 064 015 065 015 066 015 067
0000020    380d    390d    000a
         \r   8  \r   9  \n
        015 070 015 071 012
0000025

包含所有回车符(以及换行符)的单行在输出时将显示为单行,其上只有9。移除-n将导致:

$ for i in $(seq 0 9); do echo -e "\r"$i;  sleep 0.1; done | grep 5 | od -xcb
0000000    350d    000a
         \r   5  \n
        015 065 012
0000003

看起来就像正在输出5


如果你有一个进程输出由回车符而不是换行符分隔的“行”,那么就没有什么能阻止你动态更改它们以便能够将它们作为实线处理:

$ echo -e "junk\rA: good 1\rjunk\rA: good 2\rjunk" | tr '\r' '\n'  | grep '^A'
A: good 1
A: good 2

将其应用回原始问题,将其删除sleep,因为它无关紧要):

$ for i in $(seq 0 9); do echo -e -n "\r"$i; done | tr '\r' '\n' | grep 5
5

$ for i in $(seq 0 9); do echo -e -n "\r"$i; done | tr '\r' '\n' | grep 5 | od -xcb
0000000    0a35
          5  \n
        065 012
0000002