検索コマンド:リストの名前

検索コマンド:リストの名前

名前のリストを含むファイルがあります。

john
paul
ringo
george
...

その後、さまざまな名前の複数のファイルがあります。

maria.iso
jose.iso
pablo.iso
john.iso
jack.iso
jane.iso
...

findファイルリストの1つと同じ名前のファイルのみを出力するか、一致するものがない場合はファイルを出力しないコマンドを実行したいと思います。私の例では:

john

このような:

find . -type f -name "*.iso" (in array)

しかし、これが可能かどうか、それからどこから始めるべきかわかりません。

これまで私の唯一のアイデアはforループを書くことでしたが、これは醜くて非効率的に見えます。

ありがとう

答え1

readarray名前を配列として読み取るために使用されますnames。次に、配列の各要素を繰り返してコマンドを実行しますfind

readarray names < names.txt

for n in ${names[@]};do
    find . -type f -name "${n}.iso"
done

答え2

find以下で「または」テストを実行できますfind . -name a -o -name b ...

したがって、ファイルを変更してスイッチを追加し、xargsbuild find コマンドを使用します。

awk 'NR > 1 {print "-o"}; {print "-name", $0".iso"}' input-file | xargs find . 

十分に小さいリストの場合は1つだけ実行する必要がありますfind。ファイル名にスペース、引用符、またはその他の特殊文字が含まれている場合は、ASCIIヌル文字で区切られたレコードの使用を検討してください(この場合はGNU sedを使用して入力を変更できます)。 。

答え3

次のコマンドを使用すると簡単になりますzsh

names=(${(f)"$(<name-list.txt)"})

ls -ld -- **/(${(~j[|])names}).iso(D)

どこ:

  • $(<file)kshスタイル演算子、次に拡張可能file
  • fパラメータ拡張は行の分割を表示するfため$namesname-list.txt
  • j[|]:配列要素を連結するためにwithを使用します。|
  • ~|リテラルではなくグローバル演算子(ここでは置き換えに使用されます)と考えてください|
  • **/:再帰ワイルドカード(すべてのレベルのサブディレクトリから検索)
  • (D):glob修飾子dotglob(隠しファイルを含め、隠しディレクトリ検索を含むfind)はglobを有効にします。

関連情報