关注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
第一个命令的输出是预期输出。如何解释第二个命令的输出?
答案 0 :(得分:1)
当script
模拟终端时,它会将换行符(\n
)转换为回车符/换行符序列(\r\n
)。 OTOH,sed将回车解释为一行的一部分并在其后插入'$'。然后当它输出到终端时,它通过将光标移动到行的开头并继续输出来解释回车。
您可以通过将输出汇总到hexdump -C
来看到这一点。首先比较cat
和script
输出:
$ 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
这就是:
如果您仍想使用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
传递给脚本。