4

我正在做一个需要批量处理大量图像文件的项目。为了使事情更容易,我编写了一个脚本,该脚本将根据用户输入创建n目录并将文件移动到其中。m

我的问题是现在通过 shell 脚本了解目录遍历。

我在上述排序脚本的末尾添加了这个片段

dirlist=$(find $1 -mindepth 1 -maxdepth 1 -type d)

for dir in $dirlist
do
  cd $dir
  echo $dir
  ls
done

当我在包含两个内部文件夹的 Pano2 文件夹中运行它时,我总是遇到错误

./dirTravel: line 9: cd: Pano2/05-15-2012-2: No such file or directory

但是,在那之后,我从指定目录获取文件列表。

警告背后的原因是什么?如果我在获得 Pano2/ 中的文件夹列表cd ../后添加,而不是文件本身。ls

4

3 回答 3

6

我建议使用子 shell 来切换目录:

dirlist=$(find $1 -mindepth 1 -maxdepth 1 -type d)

for dir in $dirlist
do
  (
  cd $dir
  echo $dir
  ls
  )
done

子外壳中的代码不会影响父外壳,因此它可以在任何地方更改目录,而不会给您任何有关“如何返回”的问题。

这附带一个标准警告,即如果您的目录名称可能包含空格、换行符或其他意外和尴尬的字符,则整个过程会令人担忧。如果您使用可移植文件名字符集 ( [-_.A-Za-z0-9]),您将不会遇到书面问题。

于 2012-05-16T02:06:39.933 回答
3

我的猜测是,您将进入两个级别,但只会返回一个级别。尝试在 ,cd ../..之后添加 als或使用pushdandpopd代替。

例如:

for dir in $dirlist
do
  pushd $dir
  echo $dir
  ls
  popd
done

正如@shellter 指出的那样,如果这些目录有空格,那么这样的东西可能会更好:

find $1 -mindepth 1 -maxdepth 1 -type d | while read -r dir
do
  pushd "$dir"  # note the quotes, which encapsulate whitespace
  echo $dir
  ls
  popd
done
于 2012-05-16T01:47:09.720 回答
2

确实没有任何理由 cd 到目录来运行ls命令。以下应该有效:

find "$1" -mindepth 1 -maxdepth 1 -type d -exec ls {} \;

如果这只是一个示例,并且您确实运行了依赖于工作目录的其他命令,则可以将 bash -c 与 -exec 一起使用:

find "$1" -mindepth 1 -maxdepth 1 -type d -exec bash -c 'cd "$1"; echo "$1"; ls' -- {} \;

bash -c 调用会生成一个子shell,因此您无需担心它会更改当前shell 的目录。

于 2012-05-16T03:06:03.953 回答