Bash循环遍历每个子目录

huangapple go评论58阅读模式
英文:

Bash Loop iterate through each subdirectory

问题

以下脚本仅进入路径/root/Archive/EKS/data的第一个目录并创建zip文件,未切换到第二个路径/root/Incoming/data,请有人帮忙纠正我在这里做错了什么。

#!/bin/bash
startdir=(
"/root/Archive/EKS/data"
"/root/Incoming/data"
)

cd "${startdir[0]}" || exit

for sub_dir in */ ; do
    zip -r "${sub_dir%/}.zip" "$sub_dir"
done

注意:我在脚本中修改了cd命令,将其更改为进入"${startdir[0]}",这将进入第一个路径/root/Archive/EKS/data。如果您需要处理第二个路径,请修改${startdir[0]}${startdir[1]}

英文:

Below script entering into only first directory of path /root/Archive/EKS/data and making zip file, its not switching into the second path /root/Incoming/data, can you please someone correct me what I'm doing wrong here.

 #!/bin/bash
   startdir=(
"/root/Archive/EKS/data"
"/root/Incoming/data"
)

 cd "$startdir" || exit

    for sub_dir in */ ; do
        zip -r "${sub_dir%/}.zip" "$sub_dir"
    done

答案1

得分: 4

你应该循环遍历这些目录,并对cd使用subshell,类似于以下方式:

#!/usr/bin/env bash

startdir=(
  "/root/Archive/EKS/data"
  "/root/Incoming/data"
)

for dir in "${startdir[@]}"; do
 (
   cd "$dir" || exit
   for sub_dir in */ ; do
      zip -r "${sub_dir%/}.zip" "$sub_dir"
   done
 )
done
  • 没有subshell的话,在完成第一个目录后,cd会失败并显示错误消息,类似于“找不到文件或目录”。

  • 外部的for循环遍历顶级目录,而内部的循环遍历子目录。

  • 需要进行更多的测试,例如,如果没有子目录,应该发生什么?

  • 考虑在第二个for循环之前/之上使用nullglob shell选项。

  • 请参考如何检查目录是否为空?

英文:

You should loop through the directories and use a subshell for the cd, something like:

#!/usr/bin/env bash

startdir=(
  "/root/Archive/EKS/data"
  "/root/Incoming/data"
)

for dir in "${startdir[@]}"; do
 (
   cd "$dir" || exit
   for sub_dir in */ ; do
      zip -r "${sub_dir%/}.zip" "$sub_dir"
   done
 )
done

  • Without the subshell the cd would fail with an error message like, no such file or directory or something like that when it is done with the first directory.

  • The outer for loop , loops through the top directories, while the inner one loops through the sub directories.

  • Some more test needed, like if there are no subdirectories, what should happen?

  • Consider using nullglob shell option just before/above the second for loop.

  • See How Can I check if a directory is empty or not?

答案2

得分: 1

这个任务:

startdir=(
"/root/Archive/EKS/data"
"/root/Incoming/data"
)

... 将 $startdir 设置为包含两个路径名的数组。但这个命令:

cd "$startdir"

只执行一次,所以不清楚你认为它会做什么;自动并行处理整个数组吗?Bash 不是这样工作的。它只会 cd 到数组中的第一个元素,因为没有指定索引的 $startdir 会展开为第一个元素,与更明确的 ${startdir[0]} 一样。

你需要做的是循环遍历数组,并针对每个元素重复命令:

for dir in "${startdir[@]}"; do
(
  cd "$dir" || continue
  for subdir in */; do
    zip -r "${subdir%/}.zip" "$subdir"
  done
)
done
英文:

This assignment:

  startdir=(
"/root/Archive/EKS/data"
"/root/Incoming/data"
)

... sets $startdir to an array containing two pathnames. But this command:

cd "$startdir"

is only executed once, so it's not clear what you think it's going to do; automatically parallelize to process the whole array? Bash doesn't work that way. It just cd's to the first element in the array, since that's what $startdir without an index expands to (the same as the more explicit ${startdir[0]}.

What you need to do is loop over the array and repeat the commands for each element:

for dir in "${startdir[@]}"; do
(
  cd "$dir" || continue
  for subdir in */; do
    zip -r "${subdir%/}.zip" "$subdir"
  done
)
done

答案3

得分: -1

#!/bin/bash

startdirs=(
    "/root/Archive/EKS/data"
    "/root/Incoming/data"
)

for startdir in "${startdirs[@]}"; do
    cd "$startdir" || exit

    for sub_dir in */; do
        zip -r "${sub_dir%/}.zip" "$sub_dir"
    done
done
英文:

#!/bin/bash

startdirs=(
"/root/Archive/EKS/data"
"/root/Incoming/data"
)

for startdir in "${startdirs[@]}"; do
cd "$startdir" || exit

for sub_dir in */; do
    zip -r "${sub_dir%/}.zip" "$sub_dir"
done

done

huangapple
  • 本文由 发表于 2023年5月25日 09:52:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76328397.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定