stdinまたはファイルをバッファリングできるプログラム


12

一時ファイルを使用する以外に、プログラムが入力をバッファリングできる方法stdinがありますが、を取得するまでコンテンツを出力しませんEOF。シェル変数も使用したくありません(例:)buffer=$(cat)

このプログラムは次のように動作するはずです(プログラム名はであると想定buffered-cat):

$ buffered-cat
line 1
line 2
line 3
^D # Ctr-D here(End of Line)

プログラムが受け取った^Dので、buffered-cat出力は内容を出力します

line 1
line 2
line 3

私は通常sort、この目的で使用します。明らかにそれは望ましくないかもしれない副作用を持っています。
Adrian Pronk、2017年

回答:


20

貧しい人がsponge使用しているawk

awk '{a[NR] = $0} END {for (i = 1; i <= NR; i++) print a[i]}'

あなたが持っているならtac、あなたもそれを誤用することができます:

... | tac | tac

1
tacシンプルでエレガントだと思います。
Ekeyme Mo

6
@EkeymeMo | tac | tac 単純ですが、タスクにとって非常に非効率的であり、特に大きなファイルの場合、パフォーマンスに影響を与えることに注意してください。
デジタル外傷

@DigitalTraumaええ、私はその欠点を知っています。10万行のファイルをテストします。私にとっては大丈夫です。それが真実であるため、私はあなたのコメントに投票しました。
Ekeyme Mo

29

これspongeはmoreutilsから実行できます。sponge「標準入力を吸収してファイルに書き込む」。引数がない場合、そのファイルは標準出力です。このコマンドへの入力は、EOFまでメモリに格納され、その後、一度にすべて書き込まれます。

通常のファイルに書き込む場合は、ファイル名を指定するだけです。

cmd | sponge filename

の主な目的はsponge、パイプライン内で同じファイルからの読み取りと書き込みを可能にすることですが、それも必要なことを行います。


6

入力がASCIIテキストである限り(最後までNUL 0x0バイトを含まない)、sed -z必要なことを行います:

$ sed -z ''
Line 1
Line 2
Line 3
^D
Line 1
Line 2
Line 3
$ 

-z原因となるsed代わりに、通常の改行の行区切り文字としてNULバイトを処理すること。したがって、入力がNULバイトのない通常のテキストである限り、sofはEOFに達するまで入力全体をパターンバッファーに読み込み続けます。 sedその後、バッファに対して処理を行わずに出力します。


入力にNULバイトが存在する場合は、代わりにこれを行うことができます。

sed ':l;N;bl'

4

このsedソリューションは、DigitalTraumaのソリューションより少し長くなりますが、NULバイトでも機能します。

sed -n 'H;${x;s/^\n//;p}'

2
sed ':l;N;bl'も動作するはずです。
デジタルトラウマ2017年

1

あなたが求めている行動、それは単純な猫のデフォルトの行動ではありませんか?

gv@debian:$ cat << EOF #or cat <<EOF >file or cat <<EOF >/dev/stdout
> Line 1
> Line 2
> Line 3
> EOF
Line 1
Line 2
Line 3
gv@debian:$

3
いいえ、それがヒアドキュメントの振る舞いです。タイピングを試してみてくださいcat(入力)Line 1(入力)と何が起こるかを参照してください。
G-Manは 'Reinstate Monica'

はい、それはヒアドキュメント構造です。シンプルで、OPが望むものにかなり近づきます。インストールも不要
Sergiy Kolodyazhnyy 2017年

1

Pythonを除いて、muruのawkの例と同じ考えです。CtrlD行での読み取りを停止するために使用します

$ python -c 'import sys;print("".join(sys.stdin.readlines()))'                                                           
line1
line2
line3 # press Enter and Ctrl+D at this point
line1
line2
line3

2
またはperl -e 'print <>'(!)
dave_thompson_085 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.