コマンドオプションでファイルからではなくパイプから読み取ったデータを使用する


18

人の定義によると、このコマンドはファイルから入力を取得します。

$ command -r FILENAME

FILENAMEを使用して生成されたファイル名のリストを含むファイルであるとしますls > FILENAME

代わりに、コマンドにls直接結果を与えるにはどうすればよいですか?私の頭の中で、このようなことができるはずです:

$ ls | command -r

しかし、そうではなく、の出力はls引数としてフックされません。出力:

Usage: command -r FILENAME
error: -r option requires an argument

目的の効果を得るにはどうすればよいですか?


関連する質問のこれに関するより多くの答え:ファイルを期待するコマンドに文字列を渡す方法は?
イルカチュウ

回答:


31

これはコマンドに依存します。ファイルから読み取るコマンドの中には、ファイルが通常のファイルであり、そのサイズが事前にわかっており、任意の位置から読み取って巻き戻すことができるものを想定しています。これは、ファイルの内容がファイル名のリストである場合には起こりそうにありません。その場合、コマンドはおそらく最初から最後まで順番に読み取るパイプを持つコンテンツになります。ファイル名を期待するコマンドにパイプを介してデータをフィードするには、いくつかの方法があります。

  • 多くのコマンドは、ファイルを開くのではなく標準入力-から読み取ることを意味する特別な名前として扱います。これは慣習であり、義務ではありません。

    ls | command -r -
  • 多くのUNIXバリアントは/dev、標準記述子を指定する特別なファイルを提供します。/dev/stdin存在する場合、それを開いてそこから読み取ることは、標準入力から読み取ることと同等です。同様/dev/fd/0に存在する場合。

    ls | command -r /dev/stdin
    ls | command -r /dev/fd/0
  • シェルがksh、bashまたはzshである場合、シェルにファイル記述子を割り当てるビジネスを処理させることができます。この方法の主な利点は、標準入力に関連付けられていないため、標準入力を他の何かに使用でき、複数回使用できることです。

    command -r <(ls)
  • コマンドが名前に特定の形式(通常は特定の拡張子)があることを期待している場合、シンボリックリンクでそれをだますことができます。

    ln -s /dev/fd/0 list.foo
    ls | command -r list.foo

    または、名前付きパイプを使用できます。

    mkfifo list.foo
    ls >list.foo &
    command -r list.foo

にファイルのリストls生成すると、ファイルにls印刷できない文字が含まれているとファイル名が破損する傾向があるため、問題があります。printf '%s\n' *より信頼性が高い—ファイル名のすべてのバイトを文字どおりに印刷します。改行を含むファイル名は依然として問題を引き起こしますが、コマンドが改行で区切られたファイル名のリストを予期している場合、それは避けられません。


すべての可能性を列挙するための+1。IMOプロセス置換は、この状況に対する正しい答えです。
グレンジャックマン

7

そのはず:

ls | xargs -n 1 command -r

編集:空白スペースを含む名前の場合:

ls | xargs -d '\n' -n 1 command -r

commandコマンドラインで必要なすべてのファイル名を一度に持っていると信じている場合、これは問題になる可能性があります。xargsのいくつかのバージョンはcommand、一度にいくつかのファイル名(10、私には思える)を与えます。GNU xargsはすべてを一度に提供するように見えます。
ブルースエディガー

2

実際、改行を含むファイル名を含むすべてのファイル名を処理できる唯一の信頼できるソリューションは次のとおりです。

find . -maxdepth 1 -print0 | xargs -n 1 -0 command -r

この場合、ファイル名で許可されていない唯一の文字はヌル文字であり、ファイル名では許可されていません。


1

多くのコマンドは-、「標準入力を使用する」ことを意味する「ファイル名」として受け入れますが、この規則は普遍的とはほど遠いものです。manページを読んでください。


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