
ファイルが見つかった場所でコマンドを実行するにはどうすればよいですか?次の内容を含む という
名前のディレクトリがあるとします。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
zsh
glob修飾子を使用して、例えばファイルのみを選択したり.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 に処理を任せます。