【问题标题】:Linux move files without replacing if files exists如果文件存在,Linux 移动文件而不替换
【发布时间】:2016-05-01 10:59:53
【问题描述】:

在 Linux 中,如果目标中已存在特定文件,我如何在不替换的情况下移动文件?

我尝试了以下命令:

mv --backup=t <source> <dest>

文件没有被替换,但问题是扩展名被改变了,因为它把“~”放在文件名的后面。

有没有其他方法可以保留扩展名但移动时只更改文件名?

例如 test~1.txt 而不是 test.txt~1

当扩展名被替换后,您不能通过双击来查看文件。

【问题讨论】:

  • 我想你知道-n 选项到mv?这不是您所要求的(因为如果目的地存在,它什么都不做)但可能是您需要的......

标签: linux mv


【解决方案1】:

如果你想在 shell 中制作它,而不需要原子性(所以如果两个 shell 进程同时运行相同的代码,你可能会遇到麻烦),你可以(使用内置的 test(1) 功能你的外壳)

[ -f destfile.txt ] || mv srcfile.txt destfile.txt

如果您需要原子性(当两个进程同时运行时才起作用),事情就很困难了,您需要在 C 中调用一些系统调用。查看renameat2(2)

也许你应该考虑使用一些版本控制系统,比如git

【讨论】:

  • OP 想要重命名文件而不触及它们的扩展名。这没有回答问题。
【解决方案2】:

mv 有一个选项:

-S, --suffix=SUFFIX
          override the usual backup suffix

你可能会用到;但是 afaik mv 没有更改部分文件名但不更改扩展名的功能。如果您只是希望能够使用文本编辑器打开备份文件,您可以考虑以下内容:

mv --suffix=.backup.txt <source> <dest>

这是如何工作的:假设你有

-rw-r--r-- 1 chris users    2 Jan 25 11:43 test2.txt                                                                                                                                                                                                                           
-rw-r--r-- 1 chris users    0 Jan 25 11:42 test.txt

然后在命令mv --suffix=.backup.txt test.txt test2.txt 之后你会得到:

-rw-r--r-- 1 chris users    0 Jan 25 11:42 test2.txt                                                                                                                                                                                                                           
-rw-r--r-- 1 chris users    2 Jan 25 11:43 test2.txt.backup.txt

【讨论】:

  • 我很确定mv(以及类似的工具,如cpln)永远不会以任何方式解释文件名。因此它不会将. 视为具有任何特殊意义,并且它所做的唯一转换是附加一个备份后缀。这是一件好事。如果你想要一些不同的东西,那么 Bash 或 Perl 脚本可能是最好的选择。
  • @TobySpeight 我并不是说 mv 可以解释任何东西。我清楚地说“afaik mv 没有更改部分文件名但不更改扩展名的功能”。我添加了一个例子来说明我的主张;但我同意这不是 100% aandroidtest 想要的。
  • 我不是在争论 - 我的评论是对您回答的补充。只是为提问者解释 为什么 mv 无法保留现有后缀的额外信息。抱歉,如果我对您的回答提出异议!
  • @TobySpeight 我没有被冒犯 :) 只是觉得我的答案不够清楚,或者我错过了什么......
  • afaik;除非您自己开始编写脚本,否则这是不可能的;按照巴西尔的建议...
【解决方案3】:

如果移动具有相同文件名的文件,猜测 mv 命令非常有限。

下面是可以用来移动的bash脚本,如果存在同名文件,它会在文件名后面附加一个数字,并且扩展名也会被保留,以便于查看。

我修改了可以在这里找到的脚本: https://superuser.com/a/313924

#!/bin/bash
source=$1
dest=$2

file=$(basename $source)
basename=${file%.*}
ext=${file##*.}

if [[ ! -e "$dest/$basename.$ext" ]]; then
      mv "$source" "$dest"
else
      num=1
      while [[ -e "$dest/$basename$num.$ext" ]]; do
            (( num++ ))
      done
      mv "$source" "$dest/$basename$num.$ext" 
fi 

【讨论】:

  • 这要求dest 是一个目录。
【解决方案4】:

@aandroidtest:如果您能够依赖 Bash shell 脚本并且源目录(文件当前所在的位置)和目标目录(您希望它们移动到的位置)是相同的文件系统,我建议您试试我写的脚本。你可以在https://github.com/jmmitchell/movestough找到它

简而言之,脚本允许您将文件从源目录移动到目标目录,同时考虑新文件、重复(相同文件名、相同内容)文件、文件冲突(相同文件名、不同内容)、以及复制所需的子目录结构。此外,该脚本以三种形式处理文件冲突重命名。例如,如果发现/some/path/somefile.name.ext 是一个冲突文件。它将被移动到具有以下名称之一的目标目录,具体取决于所选的消除冲突样式(通过-u=--unique-style= 标志):

  • 默认样式:/some/path/somefile.name.ext-
  • 样式 1:/some/path/somefile.name..ext
  • 样式 2:/some/path/somefile..name.ext

如果您有任何问题,请告诉我。

【讨论】:

    猜你喜欢
    • 2017-05-10
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 2021-05-23
    • 2018-04-19
    • 2017-01-07
    相关资源
    最近更新 更多