Answers:
当前目录为时,可以执行以下操作parent_directory
:
for d in [0-9][0-9][0-9]
do
( cd "$d" && your-command-here )
done
该(
和)
创建一个子shell,所以当前目录没有在主脚本改变。
for f in foo bar; do cat "$f"/*.txt; done >output
在功能上等效于cat foo/*.txt bar/*.txt >output
。但是,ls
根据您传递参数的方式,它是一个会产生稍微不同的输出的命令;同样地,grep
或者wc
其输出,如果你从一个子目录运行它(但通常,要避免因为这个原因进入一个子目录精确)相对文件名会有所不同。
find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd" \;
在\( ! -name . \)
当前目录下执行命令避免。
find FOLDER* -maxdepth 0 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd" \;
-exec bash -c 'cd "$0" && pwd' {} \;
因为某些目录包含单引号和一些双引号。
-mindepth 1
pwd
直接接受的命令?”
disd(){find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c 'cd "{}" && "$@"' \;}
不行。
如果您使用的是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所建议的那样,在不使用显式循环的情况下将find输出放置到数组中的唯一正确方法将在Bash 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的要求),但是它将破坏带有空格的名称。
也可以看看:
find
在不使用显式循环的情况下将数组的输出放入数组的唯一正确方法将在Bash 4.4中使用mapfile -t -d '' dirs < <(find . -type d -print0)
。在此之前,您唯一的选择是使用循环(或将操作推迟到find
)。
dirs
数组。你可以在回路find
的输出(安全),像这样:find . -type d -print0 | while IFS= read -r -d '' file; do ...; done
。
IFS
,read
,它提供了额外的复杂性的印象。我必须考虑一下,也许有一些更简单的方法可以做到。
IFS
并且read
如您所说)已成为第二天性……它们是编写脚本的规范和惯用方式的一部分。
find . -type d -execdir echo $(pwd)/{} ';'
没有执行您想要的操作(在执行$(pwd)
之前find
已展开)…
您可以通过配管,然后使用来实现此目的xargs
。要注意的是,您需要使用-I
标志,该标志将bash命令中的子字符串替换为每个传递的子字符串xargs
。
ls -d */ | xargs -I {} bash -c "cd '{}' && pwd"
您可能要替换pwd
为要在每个目录中执行的任何命令。
如果顶层文件夹是已知的,则可以这样写:
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”。
干杯,
ls
”实例-您可以改for dir in $YOUR_TOP_LEVEL_FOLDER/*
而做。
ls $dir
表达式
尽管一个内衬适合快速,肮脏的用法,但我更喜欢在下面编写脚本时使用更详细的版本。这是我使用的模板,可以处理许多极端情况,并允许您编写更复杂的代码以在文件夹上执行。您可以在函数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"
您可以使用
find .
搜索当前目录中的所有文件/目录
比您可以像这样通过管道传递xargs命令的输出
find . | xargs 'command here'
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
cd
在子shell中进行操作。
cd
因此此代码实际上没有做任何有用的事情。
cd "$d"
这样会更好,因为它可以转移到通配符确实匹配名称包含空格和/或外壳元字符的文件的情况。