在Linux中,如果目标中已存在特定文件,如何在不替换文件的情况下移动文件?
我尝试了以下命令:
mv --backup=t <source> <dest>
该文件没有被替换,但问题是扩展名被更改,因为它在文件名的后面加上“〜”。
有没有其他方法可以保留扩展名,但只有文件名在移动时会被更改?
E.g。
test~1.txt
代替test.txt~1
当扩展程序被替换后,您不能只通过双击它来查看文件。
答案 0 :(得分:4)
如果你想在shell中创建它,而不需要原子性(所以如果两个shell进程同时运行相同的代码,你可能会遇到麻烦),你只需要(使用内置test(1)你的shell的功能)
[ -f destfile.txt ] || mv srcfile.txt destfile.txt
如果你需要原子性(当两个进程同时运行它时有效),事情就很困难了,你需要在C中调用一些系统调用。查看renameat2(2)
也许您应该考虑使用某些版本控制系统,例如git?
答案 1 :(得分:3)
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
答案 2 :(得分:1)
如果移动具有相同文件名的文件,则猜测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
答案 3 :(得分:1)
@aandroidtest:如果你能够依赖一个Bash shell脚本和源目录(目前文件所在的位置)和目标目录(你希望它们移动到哪里)是同一个文件系统,我建议你试试我写的剧本。您可以在https://github.com/jmmitchell/movestough
找到它简而言之,该脚本允许您将文件从源目录移动到目标目录,同时考虑新文件,重复(相同文件名,相同内容)文件,文件冲突(相同文件名,不同内容),以及复制所需的子目录结构。此外,该脚本以三种形式处理文件冲突重命名。例如,如果发现/some/path/somefile.name.ext
是一个冲突的文件。它将被移动到目标目录,其名称类似于以下之一,具体取决于所选择的反冲突样式(通过-u=
或--unique-style=
标志):
如果您有任何问题,请与我们联系。