如何去每个目录并执行命令?

我如何编写一个bash脚本来遍历parent_directory中的每个目录,并在每个目录中 执行一个命令

目录结构如下:

parent_directory(名称可以是任何东西 – 不遵循模式)

  • 001(目录名称遵循此模式)
    • 0001.txt(文件名遵循此模式)
    • 0002.txt
    • 0003.txt
  • 002
    • 0001.txt
    • 0002.txt
    • 0003.txt
    • 0004.txt
  • 003
    • 0001.txt

目录的数量是未知的。

当您的当前目录是parent_directory时,您可以执行以下操作:

 for d in [0-9][0-9][0-9] do ( cd $d && your-command-here ) done 

()创build一个子shell,所以当前目录在主脚本中没有改变。

Todd发布的答案帮了我。

 find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd" \; 

\( ! -name . \)避免了在当前目录下执行命令。

如果你使用的是GNU find ,你可以尝试使用-execdir参数,例如:

 find . -type d -execdir realpath "{}" ';' 

或(根据@gniourf_gniourf评论 ):

 find . -type d -execdir sh -c 'printf "%s/%s\n" "$PWD" "$0"' {} \; 

注意:您可以使用${0#./}而不是$0来修正./在前面。

或更实际的例子:

 find . -name .git -type d -execdir git pull -v ';' 

如果你想包含当前目录,使用-exec就更简单了:

 find . -type d -exec sh -c 'cd -P -- "{}" && pwd -P' \; 

或者使用xargs

 find . -type d -print0 | xargs -0 -L1 sh -c 'cd "$0" && pwd && echo Do stuff' 

或者@gniourf_gniourfbuild议的类似示例:

 find . -type d -print0 | while IFS= read -r -d '' file; do # ... done 

上面的例子支持名字中有空格的目录。


或者通过分配到bash数组中:

 dirs=($(find . -type d)) for dir in "${dirs[@]}"; do cd "$dir" echo $PWD done 

改变. 到您的特定文件夹名称。 如果你不需要recursion运行,你可以使用: dirs=(*)来代替。 上面的例子不支持在名称中包含空格的目录。

正如@gniourf_gniourfbuild议的那样,将查找的输出放入数组而不使用显式循环的唯一正确方法是在Bash 4.4中可用:

 mapfile -t -d '' dirs < <(find . -type d -print0) 

或者不是推荐的方法(涉及到lsparsing ):

 ls -d */ | awk '{print $NF}' | xargs -n1 sh -c 'cd $0 && pwd && echo Do stuff' 

上面的例子会忽略当前的目录(按照OP的要求),但是会用空格打破名字。

也可以看看:

  • Bash:在SO的每个目录
  • 如何在当前path中input每个目录并执行脚本? 在SE Ubuntu

如果顶层文件夹是已知的,你可以写这样的东西:

 for dir in `ls $YOUR_TOP_LEVEL_FOLDER`; do for subdir in `ls $YOUR_TOP_LEVEL_FOLDER/$dir`; do $(PLAY AS MUCH AS YOU WANT); done done 

在$(尽可能多的玩法); 你可以放置尽可能多的代码,只要你想要的。

请注意,我没有“cd”在任何目录。

干杯,

 for dir in PARENT/* do test -d "$dir" || continue # Do something with $dir... done 

我不明白这个文件的格式化,因为你只是想遍历文件夹…你在找这样的东西吗?

 cd parent find . -type d | while read d; do ls $d/ done 

您可以使用

 find . 

search当前目录中的所有文件/目录

比你可以像这样pipe输出xargs命令

 find . | xargs 'command here' 

虽然一个内衬是快速和肮脏的使用的好,我更喜欢下面更详细的版本来编写脚本。 这是我使用的模板,它处理许多边界情况,并允许您编写更复杂的代码以在文件夹上执行。 你可以在函数dir_command中编写你的bash代码。 下面,以dir_coomand为例,实现在git中标记每个仓库。 其余的脚本为目录中的每个文件夹调用dir_command。 迭代只通过给定的文件夹集的例子也包括在内。

 #!/bin/bash #Use set -x if you want to echo each command while getting executed #set -x #Save current directory so we can restore it later cur=$PWD #Save command line arguments so functions can access it args=("$@") #Put your code in this function #To access command line arguments use syntax ${args[1]} etc function dir_command { #This example command implements doing git status for folder cd $1 echo "$(tput setaf 2)$1$(tput sgr 0)" git tag -a ${args[0]} -m "${args[1]}" git push --tags cd .. } #This loop will go to each immediate child and execute dir_command find . -maxdepth 1 -type d \( ! -name . \) | while read dir; do dir_command "$dir/" done #This example loop only loops through give set of folders declare -a dirs=("dir1" "dir2" "dir3") for dir in "${dirs[@]}"; do dir_command "$dir/" done #Restore the folder cd "$cur" 
 for p in [0-9][0-9][0-9];do ( cd $p for f in [0-9][0-9][0-9][0-9]*.txt;do ls $f; # Your operands done ) done