これは 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