如何查找具有给定名称的目录并将其内容上移一级?

如何查找具有给定名称的目录并将其内容上移一级?

我知道如何查找具有给定名称的所有目录:

find . -name unnecessary_dir_level

以及如何将文件移动到父目录:

mv * ..

我如何组合事物 - 是

find . -name unnecessary_dir_level -exec mv {}/* {}/.. \;

要在不造成混乱的情况下完成这项工作吗?或者什么会?我不热衷于在没有建议的情况下尝试这个(并且目录太大,无法在合理的时间内备份​​)。

答案1

通过支持(无破坏)选项的实现zsh,您可以执行以下操作:mv-n

for dir (**/unnecessary_dir_level(ND/od)) () {
  (( ! $# )) || mv -n -- $@ $dir:h/ && rmdir -- $dir
} $dir/*(ND)

在哪里:

  • for var (values) cmd是循环的简短版本(在编程语言中更常见)for
  • **/: 一个全局运算符,这意味着任何级别的子目录
  • Nglob 限定符:启用nullglob该 glob(如果没有匹配,请不要抱怨)
  • Dglob 限定符:启用dotglob该 glob(包括隐藏文件)
  • /glob 限定符:限制为文件类型目录
  • odglob 限定符:order by depth (在它们所在的分支之前离开)
  • () { body; } args: 带有参数的匿名函数。
  • 这里参数being $dir/*(ND):所有文件,包括隐藏的文件$dir
  • 身体在这些文件上运行mv(如果有),然后在现在应该为空的rmdir文件上运行。$dir
  • $dir:h,(它的目录名,如 csh 中的)h的开头。$dir

请注意,这mv * ..两个帐户是错误的:

  • 它缺少选项分隔符:mv -- * ..
  • 您缺少隐藏文件:mv -- *(D) ..在 zsh 中,((shopt -s nullglob failglob; exec mv -- * ..)bash
  • 另外:如果父级中存在同名文件,您最终可能会丢失数据。
find . -name unnecessary_dir_level -exec mv {}/* {}/.. \;

无法工作,因为{}/*glob 在调用之前已由 shell 展开mv。如果当前目录中有调用的目录,它只会扩展为某个内容{},然后移动错误的文件。


你可以用findand bashwith 做类似的事情:

find . -depth -name unnecessary_dir_level -type d -exec \
  bash -O nullglob -O dotglob -c '
    for dir do
      set -- "$dir"/*
      (( ! $# )) || mv -n -- "$@" "${dir%/*}" && rmdir -- "$dir"
    done' bash {} +

答案2

版本bash>= 4.0:

shopt -s globstar nullglob dotglob
for f in **/name/; do echo mv "$f"* "$f"..; done

如果输出看起来没问题,则删除echo.

man bash

globstar:如果设置,路径名扩展上下文中使用的模式 ** 将匹配所有文件以及零个或多个目录和子目录。如果模式后跟 /,则仅目录和子目录匹配。

nullglob:如果设置,bash 允许不匹配文件的模式[...] 扩展为空字符串,而不是它们本身。

dotglob:如果设置,bash 包含以“.”开头的文件名在路径名扩展的结果中。

答案3

您可以使用for loop将每个找到的目录的内容移动到上一级。例如,我的目录temp中有文件abc

tmp/abc/
└── temp

以下命令将放入目录temptmp

for i in ` find . -name abc ` ; do mv $i/* $i/.. ; done

相关内容