如何复制包含特定文件的所有文件夹

fri*_*lle 17 command-line

我只想备份我的 FLAC 音乐文件夹。FLAC 文件可以像这样嵌套在文件夹中:

AlbumName/
??? Files/
?   ??? someSong01.flac
?   ??? someSong02.flac
??? Covers/
?   ??? someCover01.jpg
?   ??? someCover02.jpg
Run Code Online (Sandbox Code Playgroud)

如何复制和移动所有 AlbumName 的文件夹及其相应的结构和内容,其中至少包含一个 FLAC 文件中的某处(我假设这足以说明:音乐采用 FLAC 格式)

编辑: FLAC 文件可以嵌套;所以我可以有:

AlbumName2/
??? someSong01.flac
??? someSong02.flac
??? Covers/
?   ??? someCover01.jpg
|   ??? someCover02.jpg
Run Code Online (Sandbox Code Playgroud)

我想复制这些文件夹及其所有内容,而不仅仅是 FLAC 文件,并粘贴到另一个目录。

所以如果我也有

AlbumName3/
??? someSong01.mp3
??? someSong02.mp3
??? Covers/
?   ??? someCover01.jpg
|   ??? someHiddenSong.flac
Run Code Online (Sandbox Code Playgroud)

AlbumName4/
??? Files/
?   ??? someSong01.mp3
?   ??? someSong02.mp3
??? Covers/
?   ??? someCover01.jpg
?   ??? someCover02.jpg
Run Code Online (Sandbox Code Playgroud)

我想递归 cp 到另一个目录 AlbumName、AlbumName2 和 AlbumName3 但不是 AlbumName4

编辑: 没有一个答案真的在做我想做的,所以我最终使用了类似的东西:

 find -mindepth 2 -name '*.flac' -exec dirname {} \; | awk -F "/" '{print $2}' | sort -u | while read -r dirname; do cp -r "$dirname" "backup/"; done
Run Code Online (Sandbox Code Playgroud)

基本上我列出所有flac文件,我使用awk检索根文件夹,我删除重复项并做我想做的

nob*_*ody 19

一个选项是使用 rsync,它只复制 flac 文件并保留目录结构:

rsync -avzm --include=*/ --include=*.flac --exclude=* albums/ backup/
Run Code Online (Sandbox Code Playgroud)
  • 档案
  • v 冗长
  • z 在传输过程中压缩(在同一台计算机上复制可能没有用)
  • m 修剪空目录
  • 首先包括包括所有目录
  • 第二个包含包含flac文件
  • 最后一个排除排除所有其他文件

  • 原来如此。我不确定。是只需要复制flac 文件,还是需要复制至少包含一个flac 文件的整个文件夹? (2认同)

ami*_*ari 9

嗨,我的朋友,你可以使用

mkdir newdirectory
cp -r --parents */*.flac newdirectory/
Run Code Online (Sandbox Code Playgroud)

  • 请解释这个`*/*.flac`!`cp -r --parents AlbumName/ newdirectory/` 不够用吗? (4认同)
  • 从这个问题来看,flac 可能在也可能不在嵌套目录中,所以我建议启用 globstar (`shopt -s globstar`),然后使用 `**/*.flac` 作为 glob。双星将匹配零个或多个目录。 (3认同)
  • Nice 以前从未使用过`--parents`! (2认同)

bsd*_*boy 5

不错的答案

我想再补充一种方式,你也可以结合使用findcpio

find . -name "*.flac" -print0|cpio --null -pdm destination/

解释:

GNU find searches the directory tree rooted at each given file name by evaluating the given expression from left to right, according to the rules of precedence (see Operators), until the outcome is known (the left-hand side is false for AND operations, true for OR), at which point find moves on to the next file name.

GNU cpio is a tool for creating and extracting archives, or copying files from one place to another. It handles a number of cpio formats as well as reading and writing tar files.

有 3 种 cpio 模式:

  • 复制模式: In copy-out mode, cpio copies files into an archive. It reads a list of filenames, one per line, on the standard input, and writes the archive onto the standard output.

  • 复制模式: In copy-in mode, cpio copies files out of an archive or lists the archive contents. It reads the archive from the standard input.

  • 复制通过模式: In copy-pass mode, cpio copies files from one directory tree to another, combining the copy-out and copy-in steps without actually using an archive. It reads the list of files to copy from the standard input; the directory into which it will copy them is given as a non-option argument.

在这里,我们使用 Copy-pass 模式。

  • 上面命令中使用的选项:

找:

  • -name -> 文件名或使用正则表达式而不是写全名

cpio:

  • '-m, --preserve-modification-time' Retain previous file modification times when creating files.
  • '-p,--通过' Run in copy-pass mode. see ``Copy-pass mode``.
  • '-d, --make-directories' Create leading directories where needed.'
  • --quiet' 不要打印复制的块数。`

New options are the "-print0" available with GNU find, combined with the "--null" option of cpio. These two options act together to send file names between find and cpio, even if special characters are embedded in the file names.

还可以使用rsync或编写 shell 脚本来查找和复制具有目录结构的文件。

对于 Rsync 的解释,请看上面的答案。

  • 您可以通过包含对命令和您建议的选项的解释来改进您的答案。- [来自评论](https://askubuntu.com/review/first-posts/788146) (2认同)