递归复制文件并重命名

递归复制文件并重命名

如果我的输入文件夹files_input包含01-2015、等子文件夹02-201503-2015并且所有这些子文件夹都有其他子文件夹。每个子文件夹只有一个名为index.html.

如何将所有这些index.html文件复制到一个名为 的文件夹中files_output,以便它们最终像同一文件夹中的单独文件一样。它们当然应该被重命名,我已经尝试使用 --backup 来做到这一点......

我努力了

find files_input -name \*.html -exec cp --backup=t '{}' files_output \;

给它们编号,但只复制一个文件,没有其他任何内容。

我不知道这会改变什么,但我正在使用 zsh,以下是版本:

   $ zsh --version | head -1
   zsh 5.0.2 (x86_64-pc-linux-gnu)
   $ bash --version | head -1
   GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
   $ cp --version | head -1
   cp (GNU coreutils) 8.21
   $ find --version | head -1
   find (GNU findutils) 4.4.2

有想法吗?

编辑:

尝试运行例如以下

cp --backup=t files_input/01-2015/index.html files_output

连续五次仍然在files_output文件夹中给我一个index.html! cp断了吗?为什么我没有五个不同的文件?

答案1

当您是zsh用户时:

$ tree files_input
files_input
|-- 01_2015
|   |-- subfolder-1
|   |   `-- index.html
|   |-- subfolder-2
|   |   `-- index.html
|   |-- subfolder-3
|   |   `-- index.html
|   |-- subfolder-4
|   |   `-- index.html
|   `-- subfolder-5
|       `-- index.html
|-- 02_2015
|   |-- subfolder-1
|   |   `-- index.html
|   |-- subfolder-2
|   |   `-- index.html
|   |-- subfolder-3
|   |   `-- index.html
|   |-- subfolder-4
|   |   `-- index.html
|   `-- subfolder-5
|       `-- index.html
(etc.)
$ mkdir -p files_output
$ autoload -U zmv
$ zmv -C './files_input/(*)/(*)/index.html' './files_output/$1-$2-index.html'
$ tree files_output
files_output
|-- 01_2015-subfolder-1-index.html
|-- 01_2015-subfolder-2-index.html
|-- 01_2015-subfolder-3-index.html
|-- 01_2015-subfolder-4-index.html
|-- 01_2015-subfolder-5-index.html
|-- 02_2015-subfolder-1-index.html
|-- 02_2015-subfolder-2-index.html
(etc.)

这里发生的事情是我们使命令zmv可用autoload -U zmv。该命令用于重命名、复制或链接匹配的文件zsh 扩展的通配模式

我们使用zmv它的-C选项,告诉它复制文件(而不是移动它们,这是默认的)。然后,我们指定一个与我们想要复制的文件相匹配的模式,./files_input/(*)/(*)/index.html.两者(*)匹配两级子目录名称,我们将它们放在括号内,以便在每个文件的新名称中使用。每个文件的新名称是第二个参数 ,./files_output/$1-$2-index.html其中$1$2是模式中括号捕获的字符串,即对子目录名称的反向引用。两个参数都应该用单引号引起来。

答案2

你可以这样做:

cd -P files_input/.. &&
mkdir files_output   &&
pax -rws'|.*/\(.*\)/\(.*\)|\1.\2|' \
     files_input/??-2015/index.html files_output

这将全局所有index.html子目录中的文件夹中的文件./files_input用两个字符命名,然后是破折号,然后是字符串2015并将所有这些文件复制到新创建的files_output名称类似的文件夹??-2015.index.html

答案3

尝试删除周围的引号{},因为这似乎对我有用。

$ find foo* files_output -ls
 27002    0 drwxrwxr-x   2 steve    steve          60 Jul  2 15:04 foo1
 25373    0 -rw-rw-r--   1 steve    steve           0 Jul  2 15:04 foo1/index.html
 27003    0 drwxrwxr-x   2 steve    steve          60 Jul  2 15:04 foo2
 25374    0 -rw-rw-r--   1 steve    steve           0 Jul  2 15:04 foo2/index.html
 48941    0 drwxrwxr-x   2 steve    steve          40 Jul  2 15:06 files_output
$ find foo* -name index.html -exec cp --backup=t {} files_output \;
$ find files_output -ls
 48941    0 drwxrwxr-x   2 steve    steve          80 Jul  2 15:08 files_output
 51354    0 -rw-rw-r--   1 steve    steve           0 Jul  2 15:08 files_output/index.html
 49595    0 -rw-rw-r--   1 steve    steve           0 Jul  2 15:08 files_output/index.html.~1~
$

就我而言,实用程序的版本如下。

$ bash --version | head -1
GNU bash, version 4.2.53(1)-release (x86_64-redhat-linux-gnu)
$ cp --version | head -1
cp (GNU coreutils) 8.21
$ find --version | head -1
find (GNU findutils) 4.5.11
$

答案4

这对我有用:

find files_input -name "\20171123*" -exec cp --backup=t --target-directory=files_output {} +

将与“files_input”的目录和子目录中的模式匹配的所有文件复制-name到“file_output”目录,并为重复文件附加 ~1~、~2~ 等。

相关内容