4

sed のブロックバッファリングを防ごうとしているわけではありません! 私はそれをラインバッファでさえないものにしたいと思っています。

これがまったく可能かどうかはわかりません。

sed基本的に の動作とcat生の疑似端末から対話するときの動作には大きな違いがありますcat。挿入された文字を STDIN 経由で受信すると、挿入された文字をすぐに吐き出しますsedが、生のモードでもそうではありません。

思考実験を実行することができます: のような単純な sed コマンドが与えられた場合s/abc/zzz/g、 sed のような入力ストリームを sed に送信することは、せいぜい標準出力を介して文字を提供できることを意味123abします。文字列は になりますが、他の文字は入ってきたものを正確に出力します(必要に応じて「追いつく」ことができます)。したがって、ある意味で、なぜすぐに応答するのかは明らかです。する余裕があります。sed 123c123zzzcat

もちろん、sedの作成者が実際にこの種のユース ケースを気にかけている理想的な世界では、このように機能します。

そうではないのではないかと思います。実際には、それほど網羅的ではない方法sedを使用して、一致を気にすることを伝えない限り、それが何であっても行バッファーになることがわかります (これにより、3 つの z を印刷するかどうかを常に判断できます)。あなたの正規表現は改行を過ぎたり超えたりします。その場合、出力を提供する前に、いまいましいもの全体をバッファリングするだけです。

私の理想的な解決策は、行末まで待たずに、解析が完了したすべてsedのテキストを吐き出すa を見つけることです。上記の私の小さな例では、 、 、 、 、 、 、、およびが入力されている(入力されている) ときに、文字が即座に吐き​​出されます。が出力されるか、EOF の場合は出力されます。123abczzzXabXab

私はSOLですか?必要な機能を備えた Perl コードを段階的に実装する必要がありますか、それとも、この種の魔法のようにおいしい機能を何らかの構成で取得できる可能性はまだありますか?

なぜこれが必要なのかについての詳細は、私の別の質問を参照してください。

したがって、これに関する1つの潜在的な回避策は、呼び出し全体で「分割」する入力のグループを手動で確立することですsed(または、私の場合、私はすでにPerlスクリプト、perlの正規表現置換演算子を扱っているため)、手動でソートできるようにしますフラッシング。しかし、正規表現パーサーに自動的に実行させるのではなく、「バッファリング」が発生するポイントを記述するために式を熟考する必要があるため、これは同じレベルの応答性を達成することはできません。

4

2 に答える 2

3

入力ストリームを複数の正規表現に対して並行して照合し、一致するとすぐに動作するツールがあります。セドじゃない。レックスです。または GNU バージョンの flex.

このデモンストレーションを機能させるには、YY_INPUTマクロを定義する必要がありました。これは、flex がデフォルトで行バッファリング入力であったためです。レベルでのバッファリングがなくstdioても、「対話型」モードであっても、一度に 1 行未満しか処理したくないという前提があります。

したがって、これはおそらく lex の他のバージョンには移植できません。

%{
#include <stdio.h>

#define YY_INPUT(buf,result,max_size) \
   { \
   int c = getchar(); \
   result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
   }
%}

%%

abc  fputs("zzz", stdout); fflush(stdout);
.    fputs(yytext, stdout); fflush(stdout);

%%

int main(void)
{
  setbuf(stdin, 0);
  yylex();
}

使用法: そのプログラムを というファイルに入れてabczzz.l実行する

flex --always-interactive -o abczzz.c abczzz.l
cc abczzz.c -ll -o abczzz
for ch in a b c 1 2 3 ; do echo -n $ch ; sleep 1 ; done | ./abczzz ; echo
于 2013-05-29T20:47:12.630 に答える
1

実際、プログラム全体を sed で書くことができます。ファイル全体を編集バッファに丸呑みする方法を次に示します。-n を追加して印刷を抑制し、 $p を追加して、編集中の現在のバッファーで構築しているホールドスペースを切り替えた後、最後にバッファーのみを印刷するようにしました。

 sed -n 'H;$x;$p' FILENAME

遭遇するパターンに基づいて、条件付きで保留スペースを構築できます。

'/pattern/{H}'

バッファを条件付きで印刷することもできます

'/pattern/{p}'

生意気な場合は、これらの条件付きブロックをネストすることもできます。

`g' (ホールド スペースをパターン スペースにコピーして上書きするため) と s/(.).*/\1/ などの組み合わせを使用して、個々の文字を取得できます。

これが少なくとも参考になったことを願っています。別の言語でツールを作成することをお勧めします。

于 2013-05-29T18:27:53.613 に答える