我想创建一个脚本,在每个包含名为 .txt 的文件的目录中执行命令(类似于 make 命令)my_suites.cfg
。
答案1
您可以使用find
在找到指定文件的工作目录来执行命令(例如:pwd):
find /path/to/repository -type f -name my_suites.cfg -execdir pwd \;
/path/to/repository 也可以是相对路径(甚至是“.”)
答案2
由于您的标签指示bash
,您可以使用以下globstar
选项:
shopt -s globstar
for d in **/; do if [[ -f "$d/my_suites.cfg" ]]; then cd "$d"; make; cd -; fi; done
这将迭代当前目录的所有目录和子目录,检查文件是否my_suites.cfg
存在,如果存在,则更改该目录,调用make
,然后更改回原始目录。
答案3
因此,概括一下这个问题:您希望对每个具有特定名称的文件运行 bash 命令,一次一个。
假设您愿意使用现有工具而不是自己从头开始编写所有内容,以下是一些想法:
长话短说(太长了,没看完)
如果最新文件是否尚未被识别并不重要:
$ mlocate --basename --regex "^my_suites.cfg$" \
| xargs dirname \
| xargs -d '\n' <command-to-run-on-the-file>
否则,如果效率不是那么重要(假设我们~
仅在主目录()中递归搜索:
$ find ~ -name "my_suites.cfg" -type f \
| xargs dirname \
| xargs -d '\n' <command-to-run-on-the-file>
完整版
查找文件
如果您要查找的文件分散在系统各处,那么您应该关心有效性。
更快的方法
有一些缺点
$ mlocate --basename --regex "^my_suites.cfg$"
mlocate
在大多数发行版每天更新一次的数据库中查找文件路径。因此它可能无法识别最近创建或最近移动的文件。但因为它查看数据库而不是通过文件系统本身,所以它的搜索非常有效。- 该
--basename
选项指定我们正在查找文件的直接名称,不包括它的路径/目录。 - 该
--regex
选项允许在搜索模式中使用正则表达式。 (^
期望字符串从那里开始,并且$
期望字符串在那里结束。)
“始终最新”的方式
$ find / -name "my_suites.cfg" -type f
find
基本上遍历它可以找到的每个文件夹并列出名为 my_suites.cfg 的每个文件。由于它必须执行许多读取操作,因此搜索的文件夹越多,速度就越慢。- 该
-name
选项指定 my_suites.cfg 是姓名文件的目录,而不是包含我们正在查找的文件的文件夹。 - 该
-type
选项指定,我们正在寻找文件,不适用于目录、符号链接、套接字或其他东西。
对每个文件运行自定义命令
...这就是xargs
目的
一个简单的例子
$ echo "some simple example" | xargs mkdir
$ # now there are three directories, named by the echoed words
$ ls
example simple some
更复杂的事情:
$ echo "hello world" | xargs -d ' ' -I % echo 'Print a word: %'
Print a word: hello
Print a word: world
-d
option:指定哪个字符将参数彼此分隔开(此处:空格)。-I
选项:所有出现的给定字符(在本例中)都将被来自管道的参数(之前)%
替换|
这就是上面示例中发生的情况:
echo
将“hello world”打印到标准输出 (stdout
)。- 管道 (
|
) 将此值(“hello world”)提供给以下命令,该命令恰好是xargs
. xargs
搜索参数中出现的分隔符,并在找到分隔符的地方分割参数。xargs
循环遍历新创建的参数并使用参数值而不是运行命令%
进一步阅读
- Unix xargs
- 正则表达式:教程
- 找到手册页
- 这个答案也继续存在霍斯奇网站(这是我的个人网页)