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

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

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

これが私の命令です:

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

ここで、私の行は " " に似たすべてのファイルを検索しsegment.something、それをパイプの右側に渡します。 ではsomeFunction.sh、引数としてファイル名が必要です。 に入力されているファイルがあるとしますsegment1

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

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

答え1

あなたの命令

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

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

つまり、スクリプトの各呼び出しは次のようになります。

sh someFunction.sh segmentsomething

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

したがって、スクリプトでは次のようになります。

filename="$1"

echo "$filename"
cat "$filename"

以上です。通常、findファイルを検索してファイル名を渡すときにxargs、奇妙なファイル名の問題が発生することがありますが、これは人々が互いに思い出してしまいがちです。ここでもその問題について説明します。

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

したがって、いつも-print0およびfindを使用します。つまり、ファイル名はスペースで区切られるのではなく、文字 ( ) で区切られます。これにより、安全性-0が大幅に向上します。xargsnul\0

したがって:

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

答え2

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

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

とファイル名にスペースが含まれるファイルも許可します(よくある問題)。私の環境-print0では-0someFunction.sh

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

これは単にファイル名をエコーし​​、渡されたファイルの内容を書き込むだけです。someFunction.sh

関連情報