长名称的Linux mv文件


19

在Linux中,有时我会这样重命名文件:

mv dir1/dir2/dir3/file.txt  dir1/dir2/dir3/file.txt.old

请注意,我只想重命名文件,而不要将其移动到另一个目录。

有没有可以让我做该命令的简写版本的命令?我在想类似的东西:

mv dir1/dir2/dir3/file.txt  file.txt.old

甚至是类似的东西(仅在名称后面添加):

mv dir1/dir2/dir3/file.txt  {}.old

我的目标是不必再次指定完整路径。

我知道我写的那些“例子”是行不通的,但这只是我要完成的想法。

我不需要CD进入目录。


8
为什么不更改目录?它快速并且可以解决您的问题。
迈克尔·汉普顿

我正在处理来自同一位置的许多子目录,如果每次都必须返回到该父目录,它会比较慢
santiago arizti 18'Jan

3
没有人说过您必须切换到其他目录,只有您想要的目录。
迈克尔·汉普顿

请注意,(cd dir1/dir2/dir3 && exec mv file.txt{,.old})它实际上与不带子进程的代码具有相同的性能,因为exec避免了fork()在外部命令调用期间执行ing,因此您只能使用任一分支。
查尔斯·达菲

Answers:


45

对于单个文件尝试

mv dir1/dir2/dir3/file.{txt,txt.old}

X{a,b}构建扩大到Xa Xb,你可以使用有一个预览

echo dir1/dir2/dir3/file.{txt,txt.old}

看看是否适合您的需求。

注意:

  1. 用于多个文件

    mv dir1/dir2/dir3/file{1,2,3}.{txt,txt.old}
    

不可能扩展到您想要的。(这将扩展为file.txt file1.txt.old file2.txt ...的混合)

  1. {txt,txt.old}可以{,.old}根据评论缩短为

  2. 如果目录名称明确,则可以使用通配符。

    mv *1/*2/d*/*.{,old}
    

用于多个文件 rename

rename -n s/txt/old.txt/ dir1/dir2/dir3/file*.txt 

删除-n即可有效地重命名。


1
很好,我不知道这种扩展方式!谢谢你
圣地亚哥·亚利桑那

14
mv dir1/dir2/dir3/file.txt{,.old}不会也工作,甚至更短?
乔什

3
@Josh是的,它可以完美运行并且需要较少的击键。我经常使用这种结构。
rlf

2
有趣的是,您可以如何使用Linux shell多年,并且始终可以找到新的技巧
圣地亚哥·亚利桑那

我想如果我接受过bash语言的正式培训,所有这些“技巧”都会更加明显,但是我已经学到了足够的知识来相处。
圣地亚哥·亚利桑那州

6

该命令rename重命名所有匹配的文件。它的主要目的是重命名多个文件,但是如果Perl表达式仅匹配一个文件,则它将仅重命名该单个文件。有关详细信息和发行版特定的语法,请阅读联机帮助页:man rename

用法示例:将“ /path/file.txt”重命名为“ /path/file.txt.old”:

rename 's/file.txt/file.txt.old/g' /path/file.txt

较短的表示法(感谢shalomb):

rename 's/$/.old/' /path/file.txt
rename '$_.=".old"' /path/file.txt

干试使用rename -n

有关更多示例和详细信息,访问https://thepcspy.com/read/bulk-rename-files-in-ubuntu/


很酷,我知道重命名命令,只是不知道它能做的一切,谢谢!
圣地亚哥·亚利桑那州

6
不幸的是,不同的Linux发行版具有rename行为完全不同的不同命令。
卡巴斯德'18

1
对于通过附加.old文件名进行重命名的特定任务,执行rename 's/$/.old/' /path/to/file.txtrename '$_.=".old"' /path/to/file.txt
shalomb

@Fabian-我不是挑剔的,只是瞄准“最短的手”,这是OP正在寻找的一种常用习语:)
shalomb

4

对于一次性情况,如果我不想更改当前目录,则可以仅使用一个子shell:

(cd dir1/dir2/dir3/ && mv file.txt file.txt.old)

因为您cd位于子外壳中,所以您没有在实际外壳中更改目录


4
更快,更安全地使用&& exec mv-这样一来,您就不会在cd失败的情况下尝试重命名,并且exec消耗了子外壳,从而避免了性能下降。
查尔斯·达菲

同意&& 我所说的一次性案例,我不会担心子外壳的成本(保持简单:能够轻松记住如何做是更重要的IMO)
Adam

我要说的是,如果你要记住只有一条路,想起了有效的方法有助于确保你不进去的情况下效率低下的路线在那里的事情。
Charles Duffy

4

我喜欢@archemar使用{}扩展的解决方案,因为您可以在启动命令行后使用它。以下是一些完整性的可能性:

F="dir1/dir2/dir3/file.txt" ; mv "$F" "$F.old"

(仅当名称中包含空格或其他断字字符时,才需要使用引号)

mymv() {
    mv "$1/$2" "$1/$3"
}

mymv dir1/dir2/dir3 file.txt file.txt.old
mymv dir5/dir6/dir7 file.txt file.txt.old

笔记:

  • 这是bash语法,您可能正在使用其他shell
  • mymv 可以是任何合理的字符串,我使用mymv来表示“我的举动”。
  • 函数定义可以放在您的.bash_profile中

另一个:

cd dir1/dir2/dir3 ; mv file.txt file.txt.old ; cd -

(cd dir1/dir2/dir3/ && exec mv file.txt file.txt.old)

(来自@Adam和@CharlesDuffy)在CD失败的情况下可以说是更好的选择。


1
不要使用mmv,已经有一个以此方式命名的程序。
glglgl

1
@glglgl完成:)
Law29

2

如果要输入子目录以缩短mv命令,但之后又想返回当前目录,则有两种方法可以执行此操作。一种是将cdand mv放在一个子shell中(正如已经建议的那样)。

另一种是使用pushdpopd更改目录:

pushd dir1/dir2/dir3/; mv file.txt file.txt.old; popd

pushd命令类似于cd,除了它首先将当前目录的名称压入堆栈。popd从堆栈中删除顶级名称,然后切换到该目录。


pushd并且popd是用于交互使用的扩展-POSIX明确将其列出为“未指定结果”,并且为运行脚本(即在最小的嵌入式环境中)而构建的外壳不需要支持它们。
Charles Duffy

2

我会做

cd dir1/dir2/dir3/
mv file.txt file.txt.old
cd ~- # go to the most recent directory

0

涉及的解决方案:mv something{.txt,.txt.old}正在使用“ bashism”。如果您想要一种更可移植的方式,请使用常见的变量操作:

# rename all files "file*.txt" of directory /dir1/dir2/dir3 into file*.txt.old:
for f in dir1/dir2/dir3/file*.txt ; do
  mv "$f" "${f/.txt/.txt.old}"  # note there are no terminating "/"
done


# "${var/A/B}" is the content of var with the first occurence of "A" replaced by "B"

2
有关POSIX规范,请参阅pubs.opengroup.org/onlinepubs/009695399/utilities/…,这${var/text/replacement}本身就是一种bashism。
查尔斯·达菲

@CharlesDuffy哦...你让我难过:(
奥利维尔·杜拉克
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.