我正在编写一个脚本,需要在特定文件夹的每个子目录中执行一个操作。
最有效的写法是什么?
我正在编写一个脚本,需要在特定文件夹的每个子目录中执行一个操作。
最有效的写法是什么?
当前回答
如果你想在文件夹内而不是在文件夹上执行操作。
说明:您有许多pdf文件,希望将它们集中在一个文件夹中。 我的文件夹
AV 001/
AV 002/
for D in *; do cd "$D"; # VERY DANGEROUS COMMAND - DONT USE #-- missing "", it will list files too. It can go up too. for d in */; do cd "$d"; echo $d; cd ..; done; # works succesfully for D in "$(ls -d */)"; do cd "$D"; done; # bash: cd: $'Athens Voice 001/\nAthens Voice 002/' - there is no such folder for D in "$(*/)"; do cd "$D"; done; # bash: Athens Voice 001/: is folder for D in "$(`find . -type d`)"; do cd $D; done; # bash: ./Athens: there is no such folder or file for D in *; do if [ -d "${D}" ] then cd ${D}; done; # many arguments
其他回答
使用find命令。
在GNU find中,你可以使用-execdir参数:
find . -type d -execdir realpath "{}" ';'
或者使用-exec parameter:
find . -type d -exec sh -c 'cd -P "$0" && pwd -P' {} \;
或者使用xargs命令:
find . -type d -print0 | xargs -0 -L1 sh -c 'cd "$0" && pwd && echo Do stuff'
或者使用for循环:
for d in */; { echo "$d"; }
对于递归,请尝试扩展通配符(**/)(通过:shopt -s extglob启用)。
有关更多示例,请参见:如何进入每个目录并执行命令?在所以
方便的俏皮话
for D in *; do echo "$D"; done
for D in *; do find "$D" -type d; done ### Option A
find * -type d ### Option B
选项A适用于中间有空格的文件夹。而且,通常更快,因为它不会将文件夹名称中的每个单词作为单独的实体打印。
# 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
如果你想在文件夹内而不是在文件夹上执行操作。
说明:您有许多pdf文件,希望将它们集中在一个文件夹中。 我的文件夹
AV 001/
AV 002/
for D in *; do cd "$D"; # VERY DANGEROUS COMMAND - DONT USE #-- missing "", it will list files too. It can go up too. for d in */; do cd "$d"; echo $d; cd ..; done; # works succesfully for D in "$(ls -d */)"; do cd "$D"; done; # bash: cd: $'Athens Voice 001/\nAthens Voice 002/' - there is no such folder for D in "$(*/)"; do cd "$D"; done; # bash: Athens Voice 001/: is folder for D in "$(`find . -type d`)"; do cd $D; done; # bash: ./Athens: there is no such folder or file for D in *; do if [ -d "${D}" ] then cd ${D}; done; # many arguments
这将创建一个子shell(这意味着当while循环退出时,变量值将丢失):
find . -type d | while read -r dir
do
something
done
这不会:
while read -r dir
do
something
done < <(find . -type d)
如果目录名中有空格,这两种方法都可以工作。
如果目录名中有空格,则接受的答案将在空格上中断,对于bash/ksh,首选语法是$()。使用GNU find -exec选项+;如
找到……- mycommand +;#这和传递给xargs是一样的
或者使用while循环
find .... | while read -r D
do
# use variable `D` or whatever variable name you defined instead here
done