如何同时循环两个目录([A/{a,b,c}] 和 [n/{1,2,3}] 以与其内容形成对

如何同时循环两个目录([A/{a,b,c}] 和 [n/{1,2,3}] 以与其内容形成对

我不知道如何寻找这个,所以如果它在某个地方,请指导我找到答案。如果问题的标题不清楚,我也想提前道歉,我想不出更好的描述。

这是我正在尝试做的事情的简化示例。假设我有这两个目录位于不同的硬盘驱动器上:

A/data_dir1/包含:

  • dir1/
  • dir2/
  • dir3/
  • dir4/

B/info_dir1/包含:

  • dirA/
  • dirB/
  • dirC/
  • dirD/

现在,发生的情况是,如果它们按字母顺序排序,则 dir1/ 和 dirA/ 是相关的,所以我想从 dir1/ 中提取一些文件并将它们复制到 dirA/ 内。 dir2/ 和 dirB/、dir3/ 和 dirC/ 等也会发生同样的情况。

我确信有一种更简单/更好/更正确/更快的方法来做到这一点,但现在我坚持这个想法,想不出任何其他方法,所以我想做的是:

counter1=0
for info_dir in $(ls -d info_dir1/*); do
    counter1=counter1+1
    counter2=0
    for data_dir in $(ls -d data_dir1/*); do
        counter2=counter2+1
        if [[ counter1 == counter2 ]]; then
            cp $data_dir/[file2copy] $info_dir/
        fi
    done
done

我这样做的假设是它总是以正确的顺序循环两个文件夹,但我担心可能会出现问题。还有其他我忽略的方法吗?

非常感谢您提供的任何帮助!

答案1

创建两个数组,每个数组对应一组目录,然后循环索引:

data_dirs=( A/data_dir1/*/ )
info_dirs=( B/info_dir1/*/ )
n=${#data_dirs[@]}               # assume they're the same length
for (( i = 0; i < n; i++ )); do
    left="${data_dirs[i]}"
    right="${info_dirs[i]}"
    printf "%s <-> %s\n" "$left" "$right"
    # or whatever
done

shell 按字典顺序对 glob 中的文件名进行排序,因此您应该dirAdir1;配对。并dirB与等配对dir2。但最好仔细检查一下。您不需要ls,它只是一个额外的进程,不会向 shell 提供的文件名列表中添加任何内容。 (此外,它还会破坏包含空格的文件名。)

我不知道“元组样式”和语法“[A/an/1] [A/bn/2]”是什么意思。

答案2

给定目录结构,生成所需的目录名称对的一些方法如下所述:

for info_dir in info_dir1/*/; do read data_dir; echo "$data_dir" "$info_dir"; done <<< $(ls -1d data_dir1/*/)
data_dir1/dir1/ info_dir1/dirA/
data_dir1/dir2/ info_dir1/dirB/
data_dir1/dir3/ info_dir1/dirC/
data_dir1/dir4/ info_dir1/dirD/

或者

paste <(ls -1d data_dir1/*/) <(ls -1d info_dir1/*/)
data_dir1/dir1/ info_dir1/dirA/
data_dir1/dir2/ info_dir1/dirB/
data_dir1/dir3/ info_dir1/dirC/
data_dir1/dir4/ info_dir1/dirD/

或者

{ ls -d data_dir1/*/; ls -d info_dir1/*/; } | \pr -2ts" " -
data_dir1/dir1/ info_dir1/dirA/
data_dir1/dir2/ info_dir1/dirB/
data_dir1/dir3/ info_dir1/dirC/
data_dir1/dir4/ info_dir1/dirD/

答案3

zsh

data_dirs=( A/data_dir1/*(Nn/) )
info_dirs=( B/info_dir1/*(Nn/) )
for data info in ${data_dirs:^info_dirs}; do
  something with $data and $info
done

在哪里:

  • 例如,glob 限定符可以在 和 之后排序,而n不是在和 之间排序,就像在按词法排序的 glob 中通常所做的那样。numericglobsortdir10dir9dir1dir2
  • /文件类型的限制目录-/如果您还想考虑目录的符号链接,请更改为。
  • ${A:^B}压缩 2 个数组。如果它们的大小不同,则会将最长的截断为最短的大小。例如,(a b c)用 zipped(1 2)会给出(a 1 b 2).
  • 在 中zsh,您可以使用多个变量进行循环,因此for i j in a 1 b 2先使用 i=aj=1 进行循环,然后使用 i=bj=2 进行循环。

相关内容