创建子文件夹并移动文件

创建子文件夹并移动文件

我有一个名为的文件夹p/,其中p/有多个子文件夹,如下所示:

$[~/p] ls
a/ b/ c/

文件夹a/b/c/也各有多个子文件夹。我试图在 的每个文件夹和子文件夹中找到与特定模式匹配的文件,p/并将它们移动到新目录中的相应a/b/c/文件夹。因此,a/会有一个名为 的新子文件夹x/x/并将移动到 中找到的所有匹配文件a/b/会有一个名为 的新子文件夹,并将移动x/x/中找到的所有匹配文件,b/依此类推。

我努力了:

pth=path/to/p

for dir in ${pth}/*; do 
    mkdir -- "$dir/x";
    find . -name '*match*' -exec mv -t ./x '{}' +;
done

但是它不起作用,它将x/子文件夹变成了a/b/但是c/它没有移动任何东西。

我有:

mv: failed to access to './x': No such file or directory

我做错了什么?

答案1

我建议分阶段进行,首先创建目录。接下来,查找并组织搜索结果。由于您的目标在搜索范围内,因此您必须修剪目标,否则可能会导致竞争条件。现在,我们可以一次处理一个项目,但由于这会消耗大量资源,因此在移动搜索之前组织搜索通常更好,因为mv只接受一个目标会限制我们可以同时移动的文件数量。在这种情况下,我们可以使用关联数组来组织搜索,其中键成为目标。文件将被分配为字符串。重要的是引用文件名中的任何特殊字符,否则,例如,空格将被解释​​为单词拆分(或以其他方式中断)。

#!/bin/bash

builtin cd p
printf %s/x\\0 {a,b,c} | xargs -0 mkdir -p

declare -A a=()
while IFS=/ read -rd '' b c; do
    a[${b@Q}/x]+=\ "${b@Q}/${c@Q}"
done < <(find -type d -path './*/x' -prune -false -o -type f -name '*.txt' -printf %P\\0)

for k in "${!a[@]}"; do
    eval printf '%s\\0' "$k" "${a[$k]}" | xargs -0 mv --backup=t -t
done

相关内容