如何在sed管道中使用'script'命令的输出

时间:2013-05-30 07:38:20

标签: sed

关注this answer here我正在尝试使用'script'命令取消缓冲输出以用于管道。但它并没有像我期望的那样发挥作用。

我有以下文件:

$ cat test.txt
first line
second line
third line

现在,当我运行两个以下两个命令时,我希望它们的输出相同,但它们不是:

$ cat test.txt | sed -n '{s/^\(.*\)$/\^\1\$/;p;}'
^first line$
^second line$
^third line$

$ script -c "cat test.txt" -q /dev/null | sed -n '{s/^\(.*\)$/\^\1\$/;p;}'
$first line
$^second line
$^third line 

第一个命令的输出是预期输出。如何解释第二个命令的输出?

2 个答案:

答案 0 :(得分:1)

script模拟终端时,它会将换行符(\n)转换为回车符/换行符序列(\r\n)。 OTOH,sed将回车解释为一行的一部分并在其后插入'$'。然后当它输出到终端时,它通过将光标移动到行的开头并继续输出来解释回车。

您可以通过将输出汇总到hexdump -C来看到这一点。首先比较catscript输出:

$ cat test.txt | hexdump -C
00000000  66 69 72 73 74 20 6c 69  6e 65 0a 73 65 63 6f 6e  |first line.secon|
00000010  64 20 6c 69 6e 65 0a 74  68 69 72 64 20 6c 69 6e  |d line.third lin|
00000020  65 0a                                             |e.|
00000022

$ script -c "cat test.txt" -q /dev/null | hexdump -C | cat
00000000  66 69 72 73 74 20 6c 69  6e 65 0d 0a 73 65 63 6f  |first line..seco|
00000010  6e 64 20 6c 69 6e 65 0d  0a 74 68 69 72 64 20 6c  |nd line..third l|
00000020  69 6e 65 0d 0a                                    |ine..|
00000025

然后比较通过sed输出的输出:

$ cat test.txt | sed -n 's/^\(.*\)$/\^\1\$/;p;' | hexdump -C
00000000  5e 66 69 72 73 74 20 6c  69 6e 65 24 0a 5e 73 65  |^first line$.^se|
00000010  63 6f 6e 64 20 6c 69 6e  65 24 0a 5e 74 68 69 72  |cond line$.^thir|
00000020  64 20 6c 69 6e 65 24 0a                           |d line$.|
00000028

$ script -c "cat test.txt" -q /dev/null | sed -n 's/^\(.*\)$/\^\1\$/;p;' | hexdump -C
00000000  5e 66 69 72 73 74 20 6c  69 6e 65 0d 24 0a 5e 73  |^first line.$.^s|
00000010  65 63 6f 6e 64 20 6c 69  6e 65 0d 24 0a 5e 74 68  |econd line.$.^th|
00000020  69 72 64 20 6c 69 6e 65  0d 24 0a                 |ird line.$.|
0000002b

所以,当script | sed将此输出到终端时:

$first line
$^second line
$^third line

这就是:

  1. 输出“^第一行”,光标位于行尾
  2. 输出
  3. “\ r”,光标移动到行的开头(第0列)
  4. 输出“$”,覆盖“^”并将光标移动到第1列
  5. 输出
  6. “\ n”,将光标移动到下一行,但将其留在第1列
  7. “^ second line”从第1列开始输出(此时第0列没有字符),光标位于行尾
  8. 输出
  9. “\ r”,将光标移动到行的开头(第0列)
  10. “0”在第0列输出,将光标移动到第1列
  11. 输出
  12. “\ n”,将光标移动到下一行,但将其留在第1列
  13. 如果您仍想使用script,请删除\r个字符。像这样:

    script -c "cat test.txt" -q /dev/null | sed -n 's/\r//; s/^\(.*\)$/\^\1\$/;p;'
    

    请注意,即使sed输出正常,您仍会在终端上看到“阶梯”输出。我不确定为什么会发生这种情况,可能script正在修改终端设置。例如,如果通过“cat”管道输出,“阶梯”效果就会消失。

答案 1 :(得分:0)

这可能对您有用:

 script -c"cat test.txt |sed 's/.*/^&$/'" -q /dev/null

或更好:

 script -c"sed 's/.*/^&$/' test.txt" -q /dev/null

N.B。整个script传递给脚本