如何将文件从具有相同目录名称的子目录移动到其相对上层/父目录?

Luk*_*kim 6 command-line directory batch-rename

所以,我有一个这样的目录结构:

parent/
??? sub1
?   ??? source
?       ??? file1
?       ??? file2
??? sub2
?   ??? sub2.1
?       ??? source
?           ??? something1
?           ??? something2
??? sub3
    ??? sub3.1
        ??? sub3.1.1
            ??? source
                ??? other.zip
Run Code Online (Sandbox Code Playgroud)

我想将所有文件(具有不同文件名)从所有命名的目录移动source到其相对的上层/父目录。所以,结果应该是这样的:

parent/
??? sub1
?   ??? file1
?   ??? file2
?   ??? source
??? sub2
?   ??? sub2.1
?       ??? something1
?       ??? something2
?       ??? source
??? sub3
    ??? sub3.1
        ??? sub3.1.1
            ??? other.zip
            ??? source
Run Code Online (Sandbox Code Playgroud)

有没有一种简单的方法(一个班轮)来完成这个,也许使用find命令?最好是对我来说不太复杂的一个。:D 我对 Linux 很陌生。

编辑:我还将从解决方案中制作一个 bash 脚本(以便我可以轻松使用它)。例如:./movefiles.sh myfolder 那么,解决方案最好可以轻松容纳 umm 变量?,尤其是那些具有符号.(如果它是隐藏目录)#@、 等的变量。

des*_*ert 8

启用forglobstar选项的简单循环(运行shopt -s globstar以执行此操作)将完成这项工作:

dirname="source"
for i in ./**/"$dirname"/; do
  mv "$i"* "${i%$dirname/}"
done
Run Code Online (Sandbox Code Playgroud)

GNUparallel 平行安装 这个循环的等价物是:

parallel mv {}* {//}/ ::: ./**/"$dirname"/
Run Code Online (Sandbox Code Playgroud)

一种完全不同的方法是使用rename从字符串中删除“$dirname/”部分:

rename "s/$dirname\///" **/"$dirname"/*
Run Code Online (Sandbox Code Playgroud)

引用用双引号,像我一样在这里保存每个特殊字符的含义,除了$`\!。如果要在上述任何解决方案中包含“隐藏”点文件,请dotglob在运行之前设置该选项:shopt -s dotglob

解释

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

./**/source/匹配source当前目录中和下的mv每个目录,该命令将每个文件从目录内部移动到其父目录 -${i%source/}是一个参数扩展,它source/从(路径)字符串的末尾删除字符串。

示例运行

$ tree
.
??? sub1
?   ??? source
?       ??? file1
?       ??? file2
??? sub2
?   ??? sub2.1
?       ??? source
?           ??? something1
?           ??? something2
??? sub3
    ??? sub3.1
        ??? sub3.1.1
            ??? source
                ??? other.zip

$ dirname="source"
$ for i in ./**/"$dirname"/; do mv "$i"* "${i%$dirname/}"; done
$ tree
.
??? sub1
?   ??? file1
?   ??? file2
?   ??? source
??? sub2
?   ??? sub2.1
?       ??? something1
?       ??? something2
?       ??? source
??? sub3
    ??? sub3.1
        ??? sub3.1.1
            ??? other.zip
            ??? source
Run Code Online (Sandbox Code Playgroud)


wja*_*rea 4

如果你想要一个find解决方案,你可以使用这个:

find parent -name "source" -type d -exec bash -c 'cd "$1"; mv * ..' bash {} \;
Run Code Online (Sandbox Code Playgroud)

解释:

  • find parent -name "source" -type dsource- 对于以parent...命名的每个目录
  • -exec bash -c '...' bash {} \;bash- 使用as$0和目录路径 as调用 Bash$1
  • cd "$1"; mv * ..- cd 进入目录;将其所有内容上移一级。
    • 选择:mv "$1"/* "$1/.."

这或多或少是基于甜点的回答

包括隐藏文件

find parent -name "source" -type d -exec bash -c 'shopt -s dotglob; cd "$1"; mv * ..' bash {} \;
Run Code Online (Sandbox Code Playgroud)
  • shopt -s dotglob- 使 glob 包含隐藏文件