我不知道如何寻找这个,所以如果它在某个地方,请指导我找到答案。如果问题的标题不清楚,我也想提前道歉,我想不出更好的描述。
这是我正在尝试做的事情的简化示例。假设我有这两个目录位于不同的硬盘驱动器上:
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 中的文件名进行排序,因此您应该dirA
与dir1
;配对。并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 中通常所做的那样。numericglobsort
dir10
dir9
dir1
dir2
/
文件类型的限制目录。-/
如果您还想考虑目录的符号链接,请更改为。${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 进行循环。