将文件复制到另一个文件夹,如果存在则使用新名称

将文件复制到另一个文件夹,如果存在则使用新名称

我在多个位置和驱动器中有具有几乎相同文件和名称的文件夹。我想将它们全部移动到一个位置。结构如下:

Folder 1
--> Folder 1.1
-----> File1.txt
-----> File2.txt
Folder 2
--> Folder 2.1
-----> File1.txt
-----> File2.txt
...
-----> FileN.txt

我想将它们全部移动到另一个驱动器上的另一个位置。复制或移动时,我想将要移动的文件重命名为 FileN-copy-1.txt 等。这与您在 mac 上的 finder 中移动文件时的行为类似,如果您选择,它会递增地命名文件“保留两个”。

我尝试过使用 rsync,但它似乎没有可以重命名正在移动的新文件的选项。

任何帮助将不胜感激。

答案1

你可以像这样制作简单的 bash 脚本

#!/bin/bash

MyFolder=/my/folder
DestFold=/destinatin/folder
CpNum=10
i=0

for FlN in $MyFolder; do
  FlNo = echo $FlN |awk -F\/ '{print $NF}'
  if [! -f $DestFold/$FlNo ]; then
    cp $FlN $DestFold/
  else
    FlNo = echo $FlN |awk -F\/ '{print $NF}' 
    while [ $i -lt $CpNum ]; do
      i=$[$i+1]
      if [ ! -f $DestFold/${FlNo%.txt}-copy-$i.txt ]; then
        cp $FlN $DestFold/${FlNo%.txt}-copy-$i.txt
        i=$CpNum
      fi
    done
  fi
done

因此,您输入搜索和目标文件夹,然后运行脚本(在使其可执行之前)

chmod 755 yourscript

该脚本将查找文件,并将它们放入变量(FlN)中,并将变量剪切为文件名,前面不带文件夹(FlNo),如果不存在这样的文件,则进行复制。如果存在,他将创建一个文件,其中添加了-复制-X 就在文件名结尾之前(X 是副本数)。变量$CpNum将是每个文件的最大副本数(可以安全地增加)当前适用于 .txt 文件,但您可以修改它。您可以进一步添加选项来调用带有参数的脚本,或者使其成为许多不同的扩展

答案2

rsync如果您想复制目录下的所有文件和子目录,这是一个不错的首选。它确实有一个选项不是覆盖文件,-b备份选项。

但是,默认情况下,备份使用的命名方案对此无用(~文件名末尾添加的字符,某些工具将其隐藏为不需要的备份文件)。

有一个选项可以更改它(--suffix newending),可以是任何内容,但它仍然附加在最后,并且不会删除任何以前的扩展。如果这对您有用,那么这对您来说是一项简单的工作rsync。请注意,这是一个正确的备份 - 具有相同名称且在其他方​​面相同的文件不会有两个副本。

例如,在您的情况下,需要两个命令来从两个源填充目标:

rsync -av "Folder 1/" "New Folder/"
rsync -av -b --suffix -copy.txt "Folder 2/" "New Folder/"

请注意带有空格的文件所需的特殊引用,以及结尾的 / 表示目录的内容(从目录下开始,不包括它)。

文件夹 1 中已存在的文件将被添加到-copy.txt以下位置:

; ls -R1 New\ Folder
'New Folder':
f1.txt
f1.txt-copy.txt
f2.txt
f2.txt-copy.txt

更新:

这两个命令本质上从第一个目录同步到第二个目录,并且附加命令确实会覆盖目标中存在的任何内容,备份选项更改了这一点,以便将原本会被破坏的文件保留为备份。因此,实际上,第二行中的文件将保留其名称。如果命令以不同的顺序运行,这对于最初的目的仍然可能有用。

也就是说,如果您将 rsync 与备份和后缀选项一起使用 - 那么目标将azad.txt替换该文件,但备份选项将保留目标中的先前文件并使用新后缀重命名。

答案3

我将尝试在复杂性方面与这里的两个答案达成一致。以下是一个可以满足您要求的衬里:

srcdir=<Source Directory>;dstdir=<Destination Directory>;cd $srcdir;for srcfile in *;do if [ -f $dstdir$srcfile ] then $srcfile $dstdir${srcfile%.*}-copy.${srcfile##*.}; else cp $srcfile $dstdir$srcfile; fi; done

为了更具可读性,它看起来像这样:

srcdir=<Source Directory>
dstdir=<Destination Directory>

cd $srcdir

for srcfile in *
do
    if [ -f $dstdir$srcfile ]
        then 
            cp $srcfile $dstdir${srcfile%.*}-copy.${srcfile##*.}
        else
            cp $srcfile $dstdir$srcfile
    fi
done

为了解释其工作原理,您需要输入源目录和目标目录。它将 cd 进入该目录,以便 $srcfile 的格式不是完整路径,并且每次使用该变量时都不需要字符串扩展。现在它会查看 $srcdir 中的每个文件,检查该文件是否存在于 $dstdir 中,如果存在,它将插入一个 -copy,然后将文件 cp 到 $dstdir$srcfile。文件名和扩展名之间(${srcfile%.} 仅打印文件名和 ${srcfile##.} 仅打印扩展名)。如果它不存在,它将照常复制。

要解释为什么我在这里不处理多个复制案例,是因为该方案在一次性副本上没有将多个目录指定到另一个目录,因此这种情况不可能存在。也就是说,请谨慎使用,这将使用 -copy 覆盖或附加(取决于 src 与 dst 目录)文件。命名约定。

相关内容