web-dev-qa-db-ja.com

入力ファイルを引数としてパイプに渡しますか?

私には2つの問題があります。引数としてパイプを介してファイルを渡そうとしていますが、そのファイルをsh関数内の変数として使用しようとしています。

これが私のコマンドです:

find . -name 'segment*' | xargs -n1 -P4 sh someFunction.sh

ここで、私の行は「segment.something」のように見えるすべてのファイルを見つけて、それをパイプの右側に渡します。 someFunction.shでは、引数としてファイルの名前が必要です。 segment1に入力されているファイルを考えてみましょう。

someFunction.shは、(たとえば)segment1のすべての行を出力します。

パイプの左側から右側に出力を渡すにはどうすればよいですか?それからsomeFunction.sh内でそれを呼び出すにはどうすればよいですか?

2
Akshay

あなたの命令

$ find . -name 'segment*' | xargs -n1 -P4 sh someFunction.sh

someFunction.shシェルスクリプトの最大4つのコピーが並行して開始(-P 4)されるという効果があります(古いものが完了するとすぐに新しいものが生成されます)、それぞれが1つのファイル名を取得しますその引数として(-n 1)。

これは、スクリプトの各呼び出しが次のようになることを意味します

sh someFunction.sh segmentsomething

スクリプト内で、シェルは位置パラメーター(コマンドラインの引数)の値を$1$2などに配置します(通常は$0スクリプト自体の名前が含まれています)。あなたの場合、$1にはファイルの名前が含まれ、その他は空になります。

したがって、スクリプトでは:

filename="$1"

echo "$filename"
cat "$filename"

それだけです。さて、通常、findを使用してファイルを検索し、そのファイル名をxargsに渡すと、人々がお互いに思い出しがちな風変わりなファイル名の問題が発生します。ここでそれを行います。あまりにも。

findユーティリティは、空白で区切られたファイル名を渡します。スペースを含むファイル名がある場合、xargsが適切な名前でスクリプトを呼び出すのに問題が発生するため、これは適切ではありません。

したがって、常に-print0findで使用し、-0xargsで使用することをお勧めします。これは、ファイル名ではなく、スペースで区切られ、nul文字(\0)で区切られます。これにより、はるかに安全になります。

したがって:

$ find . -name 'segment*' -print0 | xargs -0 -n1 -P4 sh someFunction.sh
4
Kusalananda

someFunction.shが作業ディレクトリにあると仮定すると、このようなものを使用できます。

find . -name 'segment*' -print0| xargs -0 -n1 -P4 ./someFunction.sh 

-print0および-0は、名前にスペースが含まれるファイルを許可します(一般的な問題)。私のsomeFunction.shには

#!/bin/bash
echo "Arg: " $1  
cat $1

これは単にファイル名をエコーアウトしてから、someFunction.shに渡されたファイルの内容を書き込みます。

2
Zachary Brady