我怎样写一个bash脚本,通过每一个目录使用一个parent_directory内,在每个目录 执行 命令 。
目录结构如下:
parent_directory(名称可以是任何东西 - 犯规遵循一个模式)
- 001(目录名遵循这种模式)
- 0001.txt(文件名遵循该模式)
- 0002.txt
- 0003.txt
- 002
- 0001.txt
- 0002.txt
- 0003.txt
- 0004.txt
- 003
- 0001.txt
目录的数量是未知的。
我怎样写一个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
在(
和)
创建一个子shell,所以当前目录没有在主脚本改变。
这个答案张贴由托德帮我。
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_gniourf :
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
更改.
您的特定文件夹名。 如果你不需要递归运行,你可以使用: dirs=(*)
来代替。 上面的例子不支持目录名称中包含空格。
因此,作为@gniourf_gniourf建议,把唯一正确途径发现的输出数组中不使用显式循环将在猛砸4.4:
mapfile -t -d '' dirs < <(find . -type d -print0)
还是不推荐的方法(其中涉及的解析ls
):
ls -d */ | awk '{print $NF}' | xargs -n1 sh -c 'cd $0 && pwd && echo Do stuff'
上面的例子会忽略当前目录(由OP的要求),但它会在与空间的名称打破。
也可以看看:
如果顶层文件夹是已知的,你可以只写是这样的:
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
在$(PLAY尽可能多的,只要你想); 只要你想你可以把尽可能多的代码。
请注意,我没有任何目录“CD”。
干杯,
for dir in PARENT/*
do
test -d "$dir" || continue
# Do something with $dir...
done
虽然一个衬垫有利于快速和肮脏的使用,我更喜欢下面的脚本编写更详细的版本。 这是我使用的模板,利用许多优势情况下照顾和允许你编写更复杂的代码到一个文件夹上执行。 你可以写在函数dir_command您的bash代码。 下面,dir_coomand实现标记在GIT中每个存储库,例如, 脚本的REST调用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"
您可以通过管道,然后使用实现这一xargs
。 美中不足的是,你需要使用-I
标志将与每个传递的字符串替换子在bash命令xargs
。
ls -d */ | xargs -I {} bash -c "cd '{}' && pwd"
您可能需要更换pwd
与希望在每个目录下执行任何命令。
您可以使用
find .
搜索在当前目录recurive所有文件/迪尔斯
比你能管的输出xargs命令,像这样
find . | xargs 'command here'
我没有得到与该文件的格式化点,因为你只需要通过文件夹来迭代...您正在寻找这样的事情?
cd parent
find . -type d | while read d; do
ls $d/
done
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