bash 遍历目录的shell脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10610955/
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
Shell script to traverse directories
提问by Jason
I'm working on a project that requires batch processing of a large number of image files. To make things easier, I've written a script that will create ndirectories and move mfiles to them based on user input.
我正在做一个需要批量处理大量图像文件的项目。为了使事情更容易,我编写了一个脚本,该脚本将根据用户输入创建n目录并将m文件移动到这些目录中。
My issue is to now understand directory traversal via shell script.
我的问题是现在通过 shell 脚本了解目录遍历。
I've added this snippet at the end of the sort script described above
我在上面描述的排序脚本的末尾添加了这个片段
dirlist=$(find -mindepth 1 -maxdepth 1 -type d)
for dir in $dirlist
do
cd $dir
echo $dir
ls
done
When I ran it inside a Pano2 folder, whcih contains two inner folders, I always got an error
当我在 Pano2 文件夹中运行它时,其中包含两个内部文件夹,我总是遇到错误
./dirTravel: line 9: cd: Pano2/05-15-2012-2: No such file or directory
However, after that, I get the file listing from specified directory.
但是,在那之后,我从指定的目录中获取了文件列表。
What is the reason behind the warning? If I add cd ../after lsI get the listing of the folders inside Pano2/, but not the files themselves.
警告背后的原因是什么?如果我cd ../在ls获得 Pano2/ 中的文件夹列表而不是文件本身之后添加。
采纳答案by Nate Kohl
My guess is that you're going in two levels deep, but only coming back up one level. Try adding a cd ../..after the ls, or use pushdand popdinstead.
我的猜测是,您将进入两个级别的深度,但只能返回一个级别。尝试在cd ../..之后添加ls, 或使用pushdandpopd代替。
For example:
例如:
for dir in $dirlist
do
pushd $dir
echo $dir
ls
popd
done
As @shellter points out, if those directories have spaces, then something like this might work better:
正如@shellter 指出的那样,如果这些目录有空格,那么这样的事情可能会更好:
find -mindepth 1 -maxdepth 1 -type d | while read -r dir
do
pushd "$dir" # note the quotes, which encapsulate whitespace
echo $dir
ls
popd
done
回答by Jonathan Leffler
I recommend using a sub-shell to switch directories:
我建议使用子shell来切换目录:
dirlist=$(find -mindepth 1 -maxdepth 1 -type d)
for dir in $dirlist
do
(
cd $dir
echo $dir
ls
)
done
The code inside the sub-shell won't affect the parent shell, so it can change directory anywhere without giving you any issues about 'how to get back'.
子 shell 中的代码不会影响父 shell,因此它可以在任何地方更改目录,而不会给您任何有关“如何返回”的问题。
This comes with the standard caveat that the whole process is fraught if your directory names can contain spaces, newlines or other unexpected and awkward characters. If you keep with the portable filename character set ([-_.A-Za-z0-9]) you won't run into problems as written.
这附带了一个标准警告,即如果您的目录名称可以包含空格、换行符或其他意外和尴尬的字符,则整个过程会充满挑战。如果您使用可移植文件名字符集 ( [-_.A-Za-z0-9]),您将不会遇到书面问题。
回答by jordanm
There really isn't any reason to cd to the directory to run the lscommand. The following should work:
确实没有任何理由 cd 到目录来运行ls命令。以下应该工作:
find "" -mindepth 1 -maxdepth 1 -type d -exec ls {} \;
If that was just an example, and you really run other commands that depend on the working directory, you can use bash -c with -exec:
如果这只是一个示例,并且您确实运行了依赖于工作目录的其他命令,则可以将 bash -c 与 -exec 结合使用:
find "" -mindepth 1 -maxdepth 1 -type d -exec bash -c 'cd ""; echo ""; ls' -- {} \;
The bash -c call spawns a subshell, so you don't need to worry about it changing the directory of the current shell.
bash -c 调用会生成一个子shell,因此您无需担心它会更改当前shell 的目录。

