Linux:重命名文件但保留扩展名?

Tor*_*uun 12 linux bash rename

在 Windows/DOS 中,我可以说rename myfile.* yourfile.*更改名称但保留扩展名。这在 Linux 上是如何实现的?

手册页仅建议如何更改扩展名,但这与我想要的相反。

奖励:
我实际上想将照片的创建日期放入其文件名中,以获得类似20091231 2359 New Year.jpg. 恐怕我需要一些非平凡的命令组合来实现这一目标?

Jon*_*nik 15

这是奖金问题的答案。

我实际上想将照片的创建日期放入其文件名中,以获得类似 20091231 2359 New Year.jpg 的内容。恐怕我需要一些非平凡的命令组合来实现这一目标?

假设您想从 EXIF 数据中获取照片的创建日期,您将需要一个单独的工具。幸运的是,事实证明,它jhead提供了一种简单的方法,可以通过它的-n选项来完全按照您的意愿行事。

$ jhead -h
 [...]

 -n[format-string]

             Rename files according to date.  Uses exif date if present, file
             date otherwise.  If the optional format-string is not supplied,
             the format is mmdd-hhmmss.  If a format-string is given, it is
             is passed to the 'strftime' function for formatting
             In addition to strftime format codes:
             '%f' as part of the string will include the original file name
             [...]
Run Code Online (Sandbox Code Playgroud)

下面是一个例子:

$ jhead -n%Y-%m-%d-%f New_year.jpg   
New_year.jpg --> 2009-12-31-New_year.jpg
Run Code Online (Sandbox Code Playgroud)

编辑:当然,要对一堆照片执行此操作,它会是这样的:

$ for i in *jpg; do jhead -n%Y-%m-%d-%f $i; done
Run Code Online (Sandbox Code Playgroud)

要根据自己的喜好调整日期格式,请查看 的输出date --help,例如;它将列出可用的格式代码。

(jhead 可广泛用于不同的系统。如果您使用的是 Ubuntu 或 Debian,只需键入sudo apt-get install jhead即可安装它。)

  • 我没有想到 jhead,只是想到了重命名、统计和剪切的丑陋组合。谢谢你的好回答! (2认同)

use*_*307 10

对于重命名部分,“重命名”程序将起作用。它与您在手册页中看到的示例相同,只是切换了。

justin@eee:/tmp/q$ touch myfile.{a,b,c,d}
justin@eee:/tmp/q$ ls
myfile.a  myfile.b  myfile.c  myfile.d
justin@eee:/tmp/q$ rename -v s/myfile/yourfile/ myfile.*
myfile.a renamed as yourfile.a
myfile.b renamed as yourfile.b
myfile.c renamed as yourfile.c
myfile.d renamed as yourfile.d
justin@eee:/tmp/q$ ls
yourfile.a  yourfile.b  yourfile.c  yourfile.d
justin@eee:/tmp/q$ 
Run Code Online (Sandbox Code Playgroud)


Jam*_*ley 7

betelgeuse:tmp james$ ls myfile.* yourfile.*
ls: yourfile.*: No such file or directory   
myfile.a    myfile.b
betelgeuse:tmp james$ for file
> in myfile.*
> do
> mv "${file}" "`echo $file | sed 's/myfile\./yourfile./'`"
> done
betelgeuse:tmp james$ ls myfile.* yourfile.*
ls: myfile.*: No such file or directory
yourfile.a  yourfile.b
Run Code Online (Sandbox Code Playgroud)

关键是,如果您看过一个示例,该示例显示了如何使用正则表达式修改文件名的一部分,那么这就是您需要的唯一示例。扩展在 unix 文件系统上没有特殊地位——它们只是文件名的一部分,恰好在一个.字符之后。

  • 无需 fork+exec sed: `mv "$file" yourfile"${file#myfile}"`。适用于任何现代 Bourne-like shell(或任何 POSIX shell),但可能不适用于实际的 Bourne shell。 (5认同)

Den*_*son 7

这里有几种不同的操作文件名的方法

for f in *.jpg
do
    mv "$f" "before_part${f%.*}after_part.${f##*.}"
    # OR mv "$f" "before_part$(basename "$f" ".jpg")after_part.jpg"
done
Run Code Online (Sandbox Code Playgroud)

参数扩展mv命令如下工作:

${f%.*}- 从包含在 中的字符串的末尾删除最短的匹配模式$f,在这种情况下,删除最后一个点之后的所有内容,包括最后一个点。单曲的%意思是“距离终点最短”。

${f##*.}- 从包含在 中的字符串的开头删除最长的匹配模式$f,在这种情况下,删除最后一个点之前并包括最后一个点的所有内容(这也包括任何其他点)。双#( ##) 表示“从一开始最长”。

因此,例如,如果$f包含“Foo.bar.baZ.jpg”:

echo "${f%.*}"
Run Code Online (Sandbox Code Playgroud)

Foo.bar.baZ
Run Code Online (Sandbox Code Playgroud)

echo "${f##*.}"
Run Code Online (Sandbox Code Playgroud)

jpg
Run Code Online (Sandbox Code Playgroud)

因此mv,一旦展开,该命令将如下所示:

mv "Foo.bar.baZ.jpg" "before_partFoo.bar.baZafter_part.jpg"
Run Code Online (Sandbox Code Playgroud)