【问题标题】:how to create subfolders and move files如何创建子文件夹和移动文件
【发布时间】:2021-09-26 05:50:12
【问题描述】:

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

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

a/ b/ 和 c/ 每个也有多个子文件夹。 我试图在 p/ 的每个文件夹和子文件夹中找到与特定模式匹配的文件,并将它们移动到新目录中相应的 a/、b/ 和 c/ 文件夹中。 因此,a/ 将有一个名为 x/ 的新子文件夹,并将所有在 a/ 中找到的匹配文件移动到 x/ 中,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: 无法访问 './x': 没有这样的文件或目录

我做错了什么??你能帮帮我吗?

编辑: 这是文件夹结构的示例:

 p/
 -a/
   --t/
     --q/
       --p/
         -- files-to-match
   --f/
     --qd/
       --pe/
         -- files-to-match
   --d/
     --qu/
       --ip/
         -- files-to-match

文件夹 b 和 c 以及我拥有的其他文件夹也是如此。子文件夹的名称并不总是相同的。

@ikegami 提供给我的代码正在运行,但文件夹 x/ 的位置以“匹配文件”的同一级别结束,但我希望它位于第一级,即在同一级别 t/、f/ 和 d/(对于本示例)。

所以最终的结构是:

 p/
 -a/
   --t/
     --q/
       --p/
         -- 
   --f/
     --qd/
       --pe/
         -- 
   --d/
     --qu/
       --ip/
         -- 
   --x/
     --matched-files

【问题讨论】:

    标签: linux bash command-line terminal


    【解决方案1】:

    您没有使用正确的目录。改变

    find . -name '*match*' -exec mv -t ./x '{}' +;
    

    find "$dir" -name '*match*' -exec mv -t "$dir/x" '{}' +;
    

    此外,您需要通过排除该路径来避免从x 移动文件。

    # $pth can't start with `-`.
    # Prefix with `./` if necessary.
    # $dir won't start with `-`.
    
    pth=path/to/p
    
    for dir in "$pth"/*; do 
       mkdir "$dir/x";
       find "$dir" \
          -wholename "$dir/x" -prune \
             -or \
          -name '*match*' -exec mv -t "$dir/x" {} +
    done
    

    测试

    mkdir -p p/a/t/q/p
    touch p/a/t/q/p/abc.json
    mkdir -p p/a/f/qd/pe
    touch p/a/t/q/p/def.json
    mkdir -p p/b/t/q/p
    touch p/b/t/q/p/ghi.json
    
    pth=p
    
    find "$dir" -name '*.json'
    printf -- '--\n'
    
    for dir in "$pth"/*; do 
       mkdir "$dir/x";
       find "$dir" \
          -wholename "$dir/x" -prune \
             -or \
          -name '*.json' -exec mv -t "$dir/x" {} +
    done
    
    find "$dir" -name '*.json'
    

    输出

    p/a/t/q/p/def.json
    p/a/t/q/p/abc.json
    p/b/t/q/p/ghi.json
    --
    p/a/x/def.json
    p/a/x/abc.json
    p/b/x/ghi.json
    

    【讨论】:

    • 它没有移动匹配的文件 :( 可能我做得不对。我应该按照您的建议更改“查找”部分还是按照您将其放在第二个代码中的方式保留它??还有,-wholename、-or 和-name 中的缩进必须是这样的吗?对不起,我是初学者
    • 哎呀错字。我说你需要做的,但实际上并没有做。固定。
    • 关于“缩进 [...] 必须是这样的?”,不。这只是为了可读性。 \ 作为sh 中一行的最后一个字符会导致它被视为一个空格,并且任何数量的空格和制表符(引号之外)都与一个没有区别。
    • 非常感谢@ikegami !!现在它起作用了。如果您不介意还有一个问题,如果我想要多个 匹配例如 *.json *.txt 和 *_a_ ,我怎样才能将它们全部放在上面的相同代码中并避免运行代码 3 次??
    • 记住你可以做类似-name '*.{json,txt}'
    猜你喜欢
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多