テキストファイルの1行にある文字列セットを使用して検索コマンドを実行する方法

テキストファイルの1行にある文字列セットを使用して検索コマンドを実行する方法

これは fnames.txt というテキストファイルの内容です。

"SAMPLE_NIKE_856_20170703*"
"SAMPLE_ADIDAS_856_20170702*"
"SAMPLE_ANTA_856_20170630*"
"SAMPLE_JORDAN_856_20170627*"
"SAMPLE_CONVERSE_856_20170229*"

以下はfn.shというスクリプトです。

#!/bin/sh
#
#
while read LINE
do
    find -name "$LINE"
done < fnames.txt

何も返しません。

私が望むのは、各行でスクリプトがfindコマンドを実行し、出力をfiles.txtという別のテキストファイルに保存することです。たとえば、次のようになります。

ライン1:

find -name "SAMPLE_NIKE_856_20170703*"

次に、探しているファイル名を返します。

./SAMPLE_NIKE_856_20170703_80_20_304_234_897.dat

2号線:

find -name "SAMPLE_ADIDAS_856_20170702*

次に、探しているファイル名を返します。

./SAMPLE_ADIDAS_856_20170702_56_98_123_245_609.dat

スクリプトは、find コマンドのすべての行が実行されるまで実行され続けます。

答え1

その理由は、シェルがさまざまな拡張と引用を処理する順序によるものです。自分で入力すると

find . -name "foo*"

シェルは引用符を削除し、foo*それを引数として渡しますfind

引用符がない場合、シェルは*最初の項目にワイルドカードを実行して複数の一致が出る可能性があるため、find引用符を使用するのが賢明です。

readただし、ファイルから文字列を取得すると、変数に引用符が含まれます。今あなたがするとき

> echo $LINE
"foo*"
> echo "foo*"
foo*
> find . -name $LINE

の引用符とは異なり、引用符は$LINE削除されないことがわかりますecho "foo*"。これは、シェルが最初にecho $LINE(引用符なし)引用符を処理してから変数置換を実行して行を読み取るが、echo "foo*"引用符がまだ残っているためです。

したがって、find引用符を含むファイルが見つかります。解決策は、ファイルから引用符を削除することです。そこに引用は必要なく、行全体が変数に移動されます。

答え2

に変更IFS:

while IFS=\" read -r x LINE x; do
   find . -name "$LINE"
done < fnames.txt

$LINEこれにより、デフォルトで正しく機能するために必要な引用符が削除されます。findそれが何をするのかは、$ LINEに表示されないように読み取る行を引用符で分割することです。

答え3

ついに答えを見つけました。別のディレクトリでスクリプトを実行しているので、fnames.txtのフルファイルパスを/ path / to / my / fnames.txtとして呼び出すだけです。

#!/bin/sh
#
#
while read -r LINE
do
    find -name "$LINE"
done < /path/to/my/fnames.txt

出力:

./SAMPLE_NIKE_856_20170703_80_20_304_234_897.dat
./SAMPLE_ADIDAS_856_20170702_56_98_123_245_609.dat

関連情報