How to go to each directory and execute a command?

后端 未结 10 956
無奈伤痛
無奈伤痛 2020-12-02 04:13

How do I write a bash script that goes through each directory inside a parent_directory and executes a command in each directory

相关标签:
10条回答
  • 2020-12-02 04:29

    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 the xargs.

    ls -d */ | xargs -I {} bash -c "cd '{}' && pwd"
    

    You may want to replace pwd with whatever command you want to execute in each directory.

    0 讨论(0)
  • 2020-12-02 04:30

    If the toplevel folder is known you can just write something like this:

    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
    

    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,

    0 讨论(0)
  • 2020-12-02 04:32

    If you're using GNU find, you can try -execdir parameter, e.g.:

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

    or (as per @gniourf_gniourf comment):

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

    Note: You can use ${0#./} instead of $0 to fix ./ in the front.

    or more practical example:

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

    If you want to include the current directory, it's even simpler by using -exec:

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

    or using xargs:

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

    Or similar example suggested by @gniourf_gniourf:

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

    The above examples support directories with spaces in their name.


    Or by assigning into bash array:

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

    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:

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

    Or not a recommended way (which involves parsing of ls):

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

    The above example would ignore the current dir (as requested by OP), but it'll break on names with the spaces.

    See also:

    • Bash: for each directory at SO
    • How to enter every directory in current path and execute script? at SE Ubuntu
    0 讨论(0)
  • 2020-12-02 04:39

    you can use

    find .
    

    to search all files/dirs in the current directory recurive

    Than you can pipe the output the xargs command like so

    find . | xargs 'command here'
    
    0 讨论(0)
提交回复
热议问题