长话短说(太长了,没看完)

长话短说(太长了,没看完)

我想创建一个脚本,在每个包含名为 .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

  • -doption:指定哪个字符将参数彼此分隔开(此处:空格)。
  • -I选项:所有出现的给定字符(在本例中)都将被来自管道的参数(之前)%替换|

这就是上面示例中发生的情况:

  1. echo将“hello world”打印到标准输出 ( stdout)。
  2. 管道 ( |) 将此值(“hello world”)提供给以下命令,该命令恰好是xargs.
  3. xargs搜索参数中出现的分隔符,并在找到分隔符的地方分割参数。
  4. xargs循环遍历新创建的参数并使用参数值而不是运行命令%

进一步阅读

相关内容