ファイルが見つかった場所でコマンドを実行する

ファイルが見つかった場所でコマンドを実行する

ファイルが見つかった場所でコマンドを実行するにはどうすればよいですか?次の内容を含む という
名前のディレクトリがあるとします。testdir

$ ls -R testdir/
testdir/:
dir1  dir2  dir3  dir4  dir5

testdir/dir1:
doc1.pdf

testdir/dir2:
file1.txt

testdir/dir3:
doc2.pdf

testdir/dir4:
file2.txt

testdir/dir5:
doc5.pdf

ここで、特定のファイル/ファイル タイプを検索するアクション (コマンドの実行) を実行したいと思いますfind。たとえば、次を検索します*.pdf

$ find . -name '*.pdf'
./testdir/dir3/doc2.pdf
./testdir/dir5/doc5.pdf
./testdir/dir1/doc1.pdf

ここで、上記のコマンドがファイルを検索するコマンド (たとえばtouch file) を実行したいとします。つまり、file少なくとも 1 つ.pdfが見つかった各ディレクトリに という名前のファイルを作成し、次の結果を得たいとします。

$ ls -R testdir/
testdir/:
dir1  dir2  dir3  dir4  dir5

testdir/dir1:
doc1.pdf  file

testdir/dir2:
file1.txt

testdir/dir3:
doc2.pdf  file

testdir/dir4:
file2.txt

testdir/dir5:
doc5.pdf  file

このような作業はどうすれば実現できるでしょうか?
ファイルが見つかるたびに、cdファイルが存在する場所までコマンドを再帰的に実行するなどです。これには素晴らしい機能があること
は知っていますが、うまく動作しません。find-exec


これは、私が何をしたいのかを理解するための単なる例です。大まかに言うと、ファイルがfind再帰的に見つかったコマンドを実行するにはどうすればよいでしょうか。

答え1

このコマンドを実行するとtouch file、コマンドが開始されたディレクトリから、複数回実行される可能性があります。

find -name '*.pdf' -exec touch file \;

一方、このバリアントを実行すると、コマンドの各インスタンスはターゲット ファイルのディレクトリで実行されます。

find -name '*.pdf' -execdir touch file \;

touch fileどちらの場合も、 をおよびecho {}/または に置き換えることで、これが実際にどのように機能するかを確認できますpwd


マンページより:

-execdir command ;
-execdir command {} +

    と似ています-execが、指定されたコマンドは、一致したファイルを含むサブディレクトリから実行されます。これは通常、 を開始したディレクトリではありませんfind

答え2

次のようにして、ファイル名のディレクトリを抽出しdirname、そこから取得することができます。

find . -name "*.pdf" -type f -exec bash myscript {} \;

ファイルにはmyscript次の内容が含まれます。

dir=$(dirname "$1")
cd "$dir"
touch file

答え3

zshglob修飾子を使用して、例えばファイルのみを選択したり.pdf修飾子ディレクトリ名を配列に保存します個性的要素をcd各ディレクトリに移動してコマンドを実行します。この方法では、コマンドは一度.pdf各ディレクトリで見つかったの数に関係なく、次のようになります。

dirlist=(**/*.pdf(.:a:h))
for d in ${(u)dirlist[@]}
  (cd $d && touch file)

または

typeset -U dirlist
dirlist=(**/*.pdf(.:a:h))
for d in ${dirlist}
  (cd $d && touch file)

さらに、修飾子と限定子を組み合わせることもできます。たとえば、拡張子を使用して通常のファイル (隠しファイルと非隠しファイル) を glob し.bkp、一意のディレクトリ名を配列に保存します。

dirlist=(**/*.bkp(D.:a:h))

答え4

エントリー以外に探す必要はありません:

https://bitbucket.org/eradman/entr

entr に指定のディレクトリを監視させることもできます。find がファイルを見つけたら、そのディレクトリ内の、たとえば triggerfile.txt というファイルにアクセスし、entr に処理を任せます。

関連情報