1

この回答 hereに従って、「スクリプト」コマンドを使用して、パイプで使用する出力のバッファリングを解除しようとしています。しかし、期待どおりに機能していません。

次のファイルがあります。

$ cat test.txt
first line
second line
third line

ここで、次の 2 つのコマンドを実行すると、出力が同じであることが期待されますが、そうではありません。

$ 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 番目のコマンドの出力はどのように説明できますか?

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. 「^2行目」は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

注意: 全体がscriptscriptに渡されます。

于 2013-05-30T09:08:06.907 に答える