Linux递归复制文件到其父文件夹

Dav*_*ita 1 linux bash

我想将文件递归复制到其父文件夹以获取特定文件扩展名。例如:

./folderA/folder1/*.txt to ./folderA/*.txt  
./folderB/folder2/*.txt to ./folderB/*.txt
Run Code Online (Sandbox Code Playgroud)

等等。

我检查cpfind命令但无法让它工作。

5go*_*der 6

我怀疑当您说copy 时,您实际上是想文件移动到它们各自的父目录中。可以使用find以下方法轻松完成:

$ find . -name '*.txt' -type f -execdir mv -n '{}' ../ \;
Run Code Online (Sandbox Code Playgroud)

上面的命令递归到当前目录.,然后将以下条件级联应用于找到的每个项目:

  1. -name '*.txt'将仅过滤具有.txt扩展名的文件
  2. -type f将仅过滤掉常规文件(例如,不会过滤掉以 . 结尾的名称的目录.txt
  3. -execdir mv -n '{}' ../ \;mv -n '{}' ../ 在包含目录中执行命令其中{}是匹配文件名的占位符,需要单引号来阻止 shell 解释花括号。该;终止命令,并再次必须从外壳解释它逃脱。

我已将-n标志传递给mv程序以避免意外覆盖现有文件。

上面的命令将转换以下文件系统树

dir1/
    dir11/
        file3.txt
        file4.txt
    dir12/
    file2.txt
dir2/
    dir21/
        file6.dat
    dir22/
        dir221/
        dir221/file8.txt
        file7.txt
    file5.txt
dir3/
    file9.dat
file1.txt
Run Code Online (Sandbox Code Playgroud)

进入这个:

dir1/
    dir11/
    dir12/
    file3.txt
    file4.txt
dir2/
    dir21/
        file6.dat
    dir22/
        dir221/
        file8.txt
    file7.txt
dir3/
    file9.dat
file2.txt
file5.txt
Run Code Online (Sandbox Code Playgroud)

要摆脱空目录,请运行

$ find . -type d -empty -delete
Run Code Online (Sandbox Code Playgroud)

同样,此命令将遍历当前目录.,然后应用以下内容:

  1. -type d 这次只过滤掉目录
  2. -empty 只过滤掉那些空的
  3. -delete 删除它们。

Fine print: -execdir POSIX 没有指定,尽管主要的实现(至少是 GNU 和 BSD 的)支持它。如果您需要严格的 POSIX 合规性,您将不得不使用不太安全的方法-exec,在这种情况下需要额外考虑才能正确应用。

最后,请在带有虚拟文件的测试目录中尝试您的命令,而不是您的实际数据。尤其是使用-delete选项find,您可以比想象中更快地丢失所有数据。阅读手册页,如果这还不够,在参考手册find。如果您不理解,请不要盲目地从发布在 Internet 上的陌生人那里盲目复制 shell 命令。