如何转到每个目录并执行命令?
我如何编写一个bash脚本,该脚本在parent_directory内部的每个目录和执行 a command 。
目录结构如下:
parent_directory(名称可以是任何东西 - 不遵循模式)
- 001(目录名称遵循此模式)
- 0001.txt(文件名遵循此模式)
- 0002.TXT
- 0003.TXT
- 002
- 0001.TXT
- 0002.TXT
- 0003.TXT
- 0004.txt
- 003
- 0001.TXT
目录的数量未知。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
此答案由
\( ! -name . \)
避免在当前目录中执行命令。This answer posted by Todd helped me.
The
\( ! -name . \)
avoids executing the command in current directory.当当前目录为
parent_directory
时,您可以执行以下操作:(
和)
创建一个子 shell,因此当前目录不会更改在主脚本中。You can do the following, when your current directory is
parent_directory
:The
(
and)
create a subshell, so the current directory isn't changed in the main script.您可以通过管道然后使用 xargs 来实现此目的。问题是您需要使用
-I
标志,它将用每个xargs
传递的子字符串替换 bash 命令中的子字符串。您可能需要将
pwd
替换为您想要在每个目录中执行的任何命令。You can achieve this by piping and then using
xargs
. The catch is you need to use the-I
flag which will replace the substring in your bash command with the substring passed by each of thexargs
.You may want to replace
pwd
with whatever command you want to execute in each directory.如果您使用 GNU
find
,您可以尝试-execdir
参数,例如:或(按照 @gniourf_gniourf 评论):
注意:您可以使用
${0#./}
代替$0
来修复前面的./
。或者更实际的例子:
如果你想包含当前目录,使用
- 就更简单了exec
:或使用
xargs
:或@gniourf_gniourf :
上面的例子支持名称中带有空格的目录。
或者通过分配到 bash array:
将
.
更改为您的特定文件夹名称。如果不需要递归运行,可以使用:dirs=(*)
代替。上面的示例不支持名称中带有空格的目录。因此 @gniourf_gniourf 建议,放置输出的唯一正确方法在 Bash 4.4 中,无需使用显式循环即可在数组中查找:
或者不是推荐的方式(其中涉及 解析
ls
):上面的示例将忽略当前目录(按照 OP 的要求),但它会在带有空格的名称上中断。
另请参阅:
If you're using GNU
find
, you can try-execdir
parameter, e.g.:or (as per @gniourf_gniourf comment):
Note: You can use
${0#./}
instead of$0
to fix./
in the front.or more practical example:
If you want to include the current directory, it's even simpler by using
-exec
:or using
xargs
:Or similar example suggested by @gniourf_gniourf:
The above examples support directories with spaces in their name.
Or by assigning into bash array:
Change
.
to your specific folder name. If you don't need to run recursively, you can use:dirs=(*)
instead. The above example doesn't support directories with spaces in the name.So as @gniourf_gniourf suggested, the only proper way to put the output of find in an array without using an explicit loop will be available in Bash 4.4 with:
Or not a recommended way (which involves parsing of
ls
):The above example would ignore the current dir (as requested by OP), but it'll break on names with the spaces.
See also:
如果已知Toplevel文件夹,您可以写这样的东西:
在$上(随意播放);您可以根据需要放置任意多的代码。
请注意,我没有在任何目录上“ CD”。
干杯,
If the toplevel folder is known you can just write something like this:
On the $(PLAY AS MUCH AS YOU WANT); you can put as much code as you want.
Note that I didn't "cd" on any directory.
Cheers,
虽然一个衬里适合快速且肮脏的用法,但我更喜欢以下更多的详细版本来编写脚本。这是我使用的模板,它可以处理许多边缘情况,并允许您编写更复杂的代码以在文件夹上执行。您可以在函数dir_command中编写bash代码。在下面,dir_coomand在git中实现标记每个存储库的示例。其余的脚本调用目录中每个文件夹的dir_command。还包括仅通过给定文件夹迭代的示例。
While one liners are good for quick and dirty usage, I prefer below more verbose version for writing scripts. This is the template I use which takes care of many edge cases and allows you to write more complex code to execute on a folder. You can write your bash code in the function dir_command. Below, dir_coomand implements tagging each repository in git as an example. Rest of the script calls dir_command for each folder in directory. The example of iterating through only given set of folder is also include.
我不明白文件格式的意义,因为您只想遍历文件夹......您在寻找这样的东西吗?
I don't get the point with the formating of the file, since you only want to iterate through folders... Are you looking for something like this?
您可以使用
递归搜索当前目录中的所有文件/目录
比您可以像这样通过管道输出 xargs 命令
you can use
to search all files/dirs in the current directory recurive
Than you can pipe the output the xargs command like so
您可以在每个文件夹中以 1 行运行命令序列,例如:
You could run sequence of commands in each folder in 1 line like:
在以下代码中,您可以使用模式而不是 *过滤不需要的文件。
修改-Mindepth和MaxDepth 1到更高的数字,以便深入研究。 1的值只能达到1级。完全删除这些最小和最大深度论点,以无限深度深处。
注意:仅在您知道文件夹名称中没有空格时才使用以下代码。请参阅在这里,有关详细信息。
In the below code you are able to use a pattern instead of * to filter unwanted files.
Modify -mindepth and maxdepth 1 to a higher number in order to dive deeper. Value of 1 will go only 1 level deep. Remove these min and max depth arguments completely to go infinitely deep.
Note: Only use the below code when you know there are no spaces in the folder names. See here for details.