如何将具有重复文件名的文件复制到一个目录中,并通过自动重命名重复的文件来保留两个文件?


11

在Windows OS上,当您将文件复制到已经具有该名称的文件的目录中时,它会询问您是否要:

  1. 复制文件并替换/覆盖现有文件
  2. 取消将新文件复制到目录中
  3. 复制文件,但将其重命名(如“文件名-复制(1)”之类的名称)

当我在Ubuntu中执行此操作时,我没有第三个选项(很多时候这是一个非常有用的选项)。有什么方法可以在Ubuntu中做到这一点吗?

Answers:


17

不幸的是,鹦鹉螺没有该选项。

选项1:其他档案管理员

您可以尝试使用其他文件管理器,例如Dolphin

安装海豚(需要Universe存储库)

选项2:命令行

您还可以将命令行程序cp(1)与备份选项一起使用:

cp --backup -t DESTINATION SOURCE [SOURCE...]

这具有以下效果,可以通过以下手册的页面中所述的其他选项来控制cp(1)

--backup[=CONTROL] ―对每个现有目标文件进行备份

-b―喜欢--backup但不接受争论

-S--suffix=SUFFIX―覆盖通常的备份后缀

备份后缀为~,除非使用--suffix或设置SIMPLE_BACKUP_SUFFIX。可以通过--backup选项或VERSION_CONTROL环境变量来选择版本控制方法。这些是值:

  • noneoff:永远不要备份(即使--backup已提供)
  • numberedt:进行编号备份
  • existingnil:编号(如果存在编号的备份),否则简单
  • simplenever:总是进行简单的备份

cp --backup=existing --suffix=.orig -t ~/Videos ~/Music/*

这会将所有文件复制~/Music到中~/Videos。如果目标文件存在相同名称的文件,则通过在文件名后附加.orig名称作为备份来重命名该文件。如果存在与备份同名的文件,则备份将通过追加来重命名,.1并且该备份也存在.2,依此类推。只有这样,源文件才被复制到目标。

如果要递归复制子目录中的文件,请使用:

cp -R --backup=existing --suffix=.orig -t ~/Videos ~/Music

感谢您使用其他文件管理器的建议。不幸的是,图纳尔也没有我要指的选项。它只有:取消,全部跳过,跳过,替换,全部替换。将尝试海豚。
heisenbergman 2014年

1
海豚对此非常
有用

感谢您尝试两个。我将根据您的发现更新我的问题。
David Foerster,2014年

@heisenbergman,您好,海豚在这方面的出色表现是什么意思?它确实提供了重命名的选项,但是它仍然只允许我一个一个地重命名文件。不幸的是,“应用于所有人”选项不能与重命名选项一起使用。这对于大量文件来说是毫无用处的。这只是我的版本吗?您是否使用Dolphin一次重命名了所有双打(就像在Windows中一样)?
Kvothe

1
@ n1k31t4请--backup=existing再次阅读说明。提示:在以下情况下会发生什么touch foo bar; cp -v --backup=numbered foo bar; cp -v --backup=existing foo bar
大卫·佛斯特

2

在超级用户身上发现了这个

#!/bin/bash
cp -vn "$1" "$2"/ || cp -vn "$1" "$2"/"${1##*/}"~"$(md5sum "$1" | cut -f1 -d' ')"

具有相同名称的文件将重命名为md5sum添加到名称的文件。如果将其保存为“ saveCopy”之类的文件名,则可以使用find它来执行它:

find . -name 'z*.jpg' -exec ./saveCopy {} /tmp/Extracted/ \;

有关更多信息,请参见链接。



0

将此脚本复制到顶层目录,使其可执行并运行:

#!/bin/bash

## Get a list of all files
list=$(find . -mindepth 2 -type f -print)
nr=1

## Move all files that are unique
find . -mindepth 2 -type f -print0 | while IFS= read -r -d '' file; do
    mv -n $file ./
done
list=$(find . -mindepth 2 -type f -print)

## Checking which files need to be renamed
while [[ $list != '' ]] ; do
   ##Remaming the un-moved files to unique names and move the renamed files
   find . -mindepth 2 -type f -print0 | while IFS= read -r -d '' file; do
       current_file=$(basename $file)
       mv -n $file "./${nr}${current_file}"
   done
   ## Incrementing counter to prefix to file name
   nr=$((nr+1))
   list=$(find . -mindepth 2 -type f -print)
done
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.