1

在此处遵循此答案后,我尝试使用“脚本”命令取消缓冲输出以与管道一起使用。但它没有像我预期的那样工作。

我有以下文件:

$ 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 

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

4

2 回答 2

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. 输出“^first line”,光标在行尾
  2. 输出“\r”,光标移动到行首(第0列)
  3. 输出“$”,覆盖“^”并将光标移动到第 1 列
  4. 输出“\n”,将光标移动到下一行,但将其留在第 1 列
  5. "^second line" 从第 1 列开始输出(此时第 0 列没有字符),光标在行尾
  6. 输出“\r”,将光标移动到行首(第 0 列)
  7. "$" 在第 0 列输出,将光标移动到第 1 列
  8. 输出“\n”,将光标移动到下一行,但将其留在第 1 列
  9. 等等

如果您仍想使用script,请删除\r字符。像这样:

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

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

于 2013-05-30T09:11:14.430 回答
0

这可能对您有用:

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

或者更好:

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

注意整个script传递给script

于 2013-05-30T09:08:06.907 回答