如何在找到文件的地方执行命令?
假设我有一个名为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
在至少.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 {}
and/or来查看其实际效果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
文件和通过修饰语将目录名称保存在数组中独特的elements,然后cd
进入每个目录并运行命令。这样你就只运行你的命令一次.pdf
在每个目录中,无论在该目录中找到的 s数量是多少:
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 接管。