使用 Bash 在每个子目录中执行操作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4000613/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:48:05  来源:igfitidea点击:

Perform an action in every sub-directory using Bash

bashcommanddirectory-traversal

提问by mikewilliamson

I am working on a script that needs to perform an action in every sub-directory of a specific folder.

我正在编写一个需要在特定文件夹的每个子目录中执行操作的脚本。

What is the most efficient way to write that?

最有效的写法是什么?

采纳答案by Mike Clark

for D in `find . -type d`
do
    //Do whatever you need with D
done

回答by kanaka

A version that avoids creating a sub-process:

避免创建子流程的版本:

for D in *; do
    if [ -d "${D}" ]; then
        echo "${D}"   # your processing here
    fi
done

Or, if your action is a single command, this is more concise:

或者,如果您的操作是单个命令,则更简洁:

for D in *; do [ -d "${D}" ] && my_command; done

Or an even more concise version (thanks @enzotib). Note that in this version each value of Dwill have a trailing slash:

或者更简洁的版本(感谢@enzotib)。请注意,在此版本中,每个值D都有一个斜杠:

for D in */; do my_command; done

回答by d0x

The simplest non recursiveway is:

最简单的非递归方式是:

for d in */; do
    echo "$d"
done

The /at the end tells, use directories only.

/在年底告诉,只使用目录。

There is no need for

没有必要

  • find
  • awk
  • ...
  • awk
  • ...

回答by kenorb

Use findcommand.

使用find命令。

In GNU find, you can use -execdirparameter:

在 GNU 中find,您可以使用-execdir参数:

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

or by using -execparameter:

或使用-exec参数:

find . -type d -exec sh -c 'cd -P "
find . -type d -print0 | xargs -0 -L1 sh -c 'cd "
for d in */; { echo "$d"; }
" && pwd && echo Do stuff'
" && pwd -P' {} \;

or with xargscommand:

或使用xargs命令:

for D in *; do echo "$D"; done
for D in *; do find "$D" -type d; done ### Option A

find * -type d ### Option B


Or using forloop:

或者使用for循环:

# Option A
$ time for D in ./big_dir/*; do find "$D" -type d > /dev/null; done
real    0m0.327s
user    0m0.084s
sys     0m0.236s

# Option B
$ time for D in `find ./big_dir/* -type d`; do echo "$D" > /dev/null; done
real    0m0.787s
user    0m0.484s
sys     0m0.308s

For recursivity try extended globbing (**/) instead (enable by: shopt -s extglob).

对于递归,请尝试使用扩展的 globbing ( **/) 代替(启用:shopt -s extglob)。



For more examples, see: How to go to each directory and execute a command?at SO

更多示例,请参见:如何进入每个目录并执行命令?在 SO

回答by Sriram Murali

Handy one-liners

方便的单衬

find . -type d | while read -r dir
do
    something
done

Option A is correct for folders with spaces in between. Also, generally faster since it doesn't print each word in a folder name as a separate entity.

对于中间有空格的文件夹,选项 A 是正确的。此外,通常更快,因为它不会将文件夹名称中的每个单词作为单独的实体打印出来。

while read -r dir
do
    something
done < <(find . -type d)

回答by Paul Tomblin

find . -type d -print0 | xargs -0 -n 1 my_command

find . -type d -print0 | xargs -0 -n 1 my_command

回答by Paused until further notice.

This will create a subshell (which means that variable values will be lost when the whileloop exits):

这将创建一个子shell(这意味着当while循环退出时变量值将丢失):

#!/bin/bash
###  == the first args to this script
### usage: script.sh /path/to/dir/

for f in `find . -maxdepth 1 -mindepth 1 -type d`; do
  cd "$f"
  <your job here>
done

This won't:

这不会:

find .... |  while read -r D
do
  ...
done 

Either one will work if there are spaces in directory names.

如果目录名称中有空格,任何一种都可以使用。

回答by Henry Dobson

You could try:

你可以试试:

##代码##

or similar...

或类似...

Explanation:

解释:

find . -maxdepth 1 -mindepth 1 -type d: Only find directories with a maximum recursive depth of 1 (only the subdirectories of $1) and minimum depth of 1 (excludes current folder .)

find . -maxdepth 1 -mindepth 1 -type d:只查找最大递归深度为1(仅$1的子目录)和最小深度为1(不包括当前文件夹.)的目录

回答by ghostdog74

the accepted answer will break on white spaces if the directory names have them, and the preferred syntax is $()for bash/ksh. Use GNU find-execoption with +;eg

如果目录名称有空格,则接受的答案将在空格处中断,并且首选语法是$()bash/ksh。使用GNU find-exec选项与+;例如

find .... -exec mycommand +;#this is same as passing to xargs

find .... -exec mycommand +;#this is same as passing to xargs

or use a while loop

或使用 while 循环

##代码##