ed(1) スクリプト実行時の標準入力エコー

ed(1) スクリプト実行時の標準入力エコー

次のedスクリプトが与えられたら

$ cat helloworld
a
hello
world
.
,n
,s,o,O,g
,n
Q

何とかインタラクティブな出力を得たいです。

$ ed
a
hello
world
.
,n
1   hello
2   world
,s,o,O,g
,n
1   hellO
2   wOrld
Q
$

期待ではなく

$ cat helloworld | ed
1   hello
2   world
1   hellO
2   wOrld
$

おそらく、サードパーティのユーティリティを使用してこれは可能ですか?よろしくお願いします!

編集する:やる気を追加する必要があると思いました。いくつかのサンプル編集セッションを作成し、これをscript(1)。長い編集セッション(さらに悪い)

答え1

わかりました。

 awk '{ print; system("sleep 0") }' edscript | tee /dev/tty | ed

または以下なしtee

awk '{ print >"/dev/stderr"; print | "ed"; system("sleep 0") }' edscript

print >"/dev/stderr"システムで機能しない場合は使用できますprint | "cat >&2"


そしてgnu sed

sed -u -n -e 'p;w /dev/stderr' -e 's|.*||e' edscript | ed

同様に効果的な別の方法:
使用splitを分割することです。スクリプトの編集各行:

split -l1 edscript

xaaその後、...xab動作するのと同じ結果が出ますxah
その後、次の部品を使用できます。

for i in x*; do awk '{ print >"/dev/stderr"; print }' $i; done | ed

または

for i in x*; do sed -n -e 'p;w /dev/stderr' $i; done | ed

期待される結果を得るために。だからあなたはrm x*...

答え2

ユーザーがコマンドを入力して応答を待つ対話型端末セッションをシミュレートしたいと思う(または目標が次のようになると仮定)ed時々応答を待ってから)他のコマンドなどを入力してください。これを行うためのスクリプトを書くことができますが、各行のexpect間にしばらく停止し、端末とターゲットプロセスに一度に1行ずつ送信するだけで十分です。

    $ while IFS= read -r line
      do
        printf '%s\n' "$line" >/dev/tty
        printf '%s\n' "$line"
        sleep 0.5
      done < helloworld | ed
a
hello
world
.
,n
1   hello
2   world
,s,o,O,g
,n
1   hellO
2   wOrld
Q

入力と出力をよりよく区別するために、行に色やその他のハイライトを追加できます。あるいは、この特別な場合は、
echo "$line" >/dev/tty(コマンド)でプロンプト文字を有効にして、各コマンドの前にaが表示されるようにすることもできます。edP*ed

答え3

私は何かをしました...複雑なことでした。私は最近ex調査してきましたed- 私はあまりうまくいきませんが - これはより深く探求する機会になりました。まず、edスクリプトを解析してedストリーム内に渡します。

b='[:blank:]'
sed -e 'h;/\n/!i\' -e 0i -e 's/^\(.*[^\]\)*\(\\\\\)*\\$//;tn'"
/^\n*\([0-9;$,.$b]*[gGvV].*\\\\\n[$b]*\)*\([0-9,$.;${b}]*[aic][$b]*\)\
\(\n\(.*\)\n\.\)*\(\n.*\)*$/{ s//\4/;:n" -e 'G;//{N;D
    };g;s//\1\2/;l;x;s//\4/;l;H;s/.*/./;a\' -e '.
};l;g;i\' -e .\\ -e 1,.p\\ -e u <ed_script | ed

以前ほど複雑ではありません。これで、ほぼすべての複雑さが2行にわたる単一の正規表現に集中しています。この長い正規表現は、スクリプト全体のほぼすべてのテストを処理します。

私が知る限り、アイデアはあなたが到達できることです入れるapend、insert、またはchangeコマンドのいずれかを使用するモード入れるその後、パターンは.文字通りドットのみで構成される次の行にすべての入力を取得します。複数行にまたがる他の連続コマンド(または含まれるシーケンスでも)Gは、後続のバックスラッシュとともに次の行に続く必要があります。しかし、いつものように、バックスラッシュはそのコンテキストでそれ自体でエスケープされます。gVv\\

したがって、私が間違っている可能性は十分ですが、考えるこれはすべての状況を処理します。一連の[aic]... ポイント.と一致しない各入力ラインに対して、sed次の一連のコマンドを挿入します。

0i
command-line$
.
1,.p
u

... 明示的な ook のed挿入を表します。il(作成したとおりsed独自の順序でp印刷し、最後にすべてのu操作を実行します。編集を終え、印刷して反転する非常に便利な結果を得ます。そして単一の操作で最後のアドレスを回復します。

以下の基準を満たす方を対象にするより複雑な一連の末尾のバックスラッシュ[aic]と一致します。.このような場合は、sedシリーズの終わりに達するまで再帰的にドラッグしてからl操作を実行します。[aic]、および実際のテキスト入力を別々の印刷物に分割することに注意してください.。各タイプには独自のookがあるため、lテキスト入力はできるだけ一緒にリンクされています。(デフォルトでは、ook出力はsed80文字で中断されますl。)

お見せする方が簡単になりそうでした。以下からわかります?。これは、以前に提供されたコマンドが有効なコマンドではなかったために発生します。 - 破損した入力gによるものではありません。sed(私は希望)。以下は、サンプルデータセットの変更されたバージョンの出力です。

g \\\n  a$
hello\nworld\\\n\n  0a\n  world\\\nworld\nworld$
.$
?
,n$
1       hello
2       world\
3
4         0a
5         world\
6       world
7       world
,s,o,O,g$
4$
  0a
.,$n$
4         0a
5         wOrld\
6       wOrld
7       wOrld
,s,$,\\\n\\\n\\\\$
\
,n$
1       hellO
2
3       \
4       wOrld\
5
6       \
7
8
9       \
10        0a
11
12      \
13        wOrld\
14
15      \
16      wOrld
17
18      \
19      wOrld
20
21      \
Q$

関連情報