コマンド出力を他のコマンドにパイプする方法は?


83

例:

ls | echo何も印刷しません(実際には空白行)。ファイルのリストを印刷することを期待しています。

ls | grep 'foo'一方、期待どおりに動作します(名前に「foo」が含まれるファイルを出力します)。

これらの状況で私がやることは次のようなものです。 ls | while read OUT; do echo $OUT; doneしかし、これはかなり面倒です。

パイピングが一部のコマンドで機能するが、他のコマンドでは機能しないのはなぜですか?この問題を回避するにはどうすればよいですか?


2
何をするls | echoつもりですか?なぜ単に実行しないのlsですか?
テオメガ

12
私のポイントを説明する最も簡単な例を使用しました。オブジェクトストア内のgitオブジェクトとそのタイプを表示するワンライナーを作成しようとしたときに、実際にこの問題に遭遇しました。したがって、オブジェクトIDをにパイプしましたがgit cat-file、機能しませんでした。どうやらエコーは同じ振る舞いをしているので、例として使用しました。
ミハイロタル

また、xargsの-nコマンドを見て、サブコマンドに付ける引数の数を示します。`... | xargs -n1 git cat-file`
リッチ

回答:


118

コマンドライン引数と標準入力には違いがあります。パイプは、あるプロセスの標準出力を別のプロセスの標準入力に接続します。そう

ls | echo

lsの標準出力をechoの標準入力に接続します。いいね?まあ、エコーは標準入力を無視し、コマンドライン引数をダンプします-この場合はありません-それ自身の標準出力。出力:何もありません。

この場合、いくつかの解決策があります。1つは、標準入力を読み取り、標準出力にダンプするコマンド(catなど)を使用することです。

ls | cat

あなたの仕事の定義に応じて、「働く」でしょう。

しかし、一般的なケースはどうでしょう。本当に欲しいのは、あるコマンドの標準出力を別のコマンドのコマンドライン引数に変換することです。他の人が言ったように、xargsこの場合の標準的なヘルパーツールは、stdinからコマンドのコマンドライン引数を読み取り、実行するコマンドを構築します。

ls | xargs echo

置換コマンドを使用して、これを変換することもできます $()

echo $(ls)

また、あなたが望むことをします。

これらのツールはどちらもシェルスクリプトの核となるものなので、両方を学ぶ必要があります。

完全を期すために、質問で示したように、stdinをコマンドライン引数に変換するもう1つの基本的な方法は、シェルの組み込みreadコマンドです。「単語」(IFS変数で定義された単語)を一時変数に変換します。これは、任意のコマンド実行で使用できます。


1
非常に役立つ有益な回答、ありがとう!私は現在bashを学んでおり、xargsと$(*)表記の両方を見たことがありますが、それらにはあまり注意を払いませんでした。今、私はそれらがどれほど重要であるかを知っており、間違いなくそれらを調べます。
ミハイRotaru

1
xargsはOPが探していたものでした。
イクティス

19

ls | echoecho入力を読み取らないため、空白行のみを出力します。パイプラインの最後のコマンドは、実際にechoは空白行のみを出力するものです。

一般的に:

a | b

の出力がaの入力になるようにしますb。のPipelinesセクションを読むことをお勧めしますman bash


本当に使いたい場合はlsechoいくつかの(かなり役に立たない)例があります。

ls | xargs -L 1 echo
echo `ls`
for i in `ls` ; do echo $i ; done

11

あなたがしたい場合は、コマンド試してください。echols

ls | xargs echo

これはechoの出力で呼び出しますls


3
またはls | xargs -I {} echo {}、各行ごとに個別に
呼び出す

3

単に使用しないのはなぜですか:

echo `ls`

またははるかに安全:

echo "`ls -lrt`"

4
それともただecho *
カザール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.