递归地将文件扩展名添加到所有文件


106

我有一些目录和子目录,其中包含没有文件扩展名的文件。我想添加.jpg到这些目录中包含的所有文件。我见过bash脚本用于更改文件扩展名,而不仅仅是添加一个。它也需要递归,有人可以帮忙吗?

Answers:


228

没有显式循环(man find)的备用命令:

find . -type f -exec mv '{}' '{}'.jpg \;

说明:这-type f将从当前目录()开始递归地查找所有文件().,并将move命令(mv)应用于每个文件。还要注意周围的引号{},以便正确处理带有空格(甚至是换行符...)的文件名。


7
特别是,如果目录结构中有大量文件,则此方法效果更好(使bash对要遍历的文件列表的长度感到不满)。
DrAl

@Al,如果您引用for循环破坏bash以遍历文件列表,那是不正确的。bash for循环迭代地发出每个mv命令。
NIK

问题:执行语句之前是否find先设置文件列表?我想是的,但是想在编码无限循环之前弄清楚这一点。-exec
Boldewyn

2
此命令还将查找带有扩展名的文件。那是OP想要的吗?
ghostdog74

1
@ ghostdog74:自从他接受了这个答案以来,上面的方法显然可以解决问题。否则,正如您在下面提到的,添加-not -name "*.*"将达到目的。
09年

62

这将查找没有扩展名的文件并添加您的.jpg

find /path -type f -not -name "*.*" -exec mv "{}" "{}".jpg \;

这绝对会在99%的时间内提供所需的结果。+1
les

9

这有点晚了,但是我想我想补充一点,比到目前为止的解决方案更好的解决方案(尽管可能可读性较差)是:

find /path -type f -not -name "*.*" -print0 | xargs -0 rename 's/(.)$/$1.jpg/'

使用该find | xargs模式通常可以提高执行效率,因为您不必为每个文件派生一个新进程。

请注意,这需要在Debian风格的发行版中找到的重命名版本(又名prename),而不是传统的重命名。但是,这只是一个很小的perl脚本,因此在任何系统上使用上面的命令都足够容易。


4

像这样,

for f in $(find . -type f); do mv $f ${f}.jpg; done

我不希望您使用空格分隔文件名,
如果这样做,则需要稍微处理一下文件名。

如果你想从其他目录下执行命令,
你可以代替find .find /target/directory


1
缺少一个“ do”,如果文件名中有空格,则最好引用文件名:对于$ {find。-type f)中的f;做MV“ $ f”“ $ {f} .jpg”; 完成
DrAl

大概我将从顶级目录中运行它?
robjmills

@seengee:是的。请注意,此命令还会错过中的破折号-type
09年

我必须去某个地方,打字速度太快...现在修复。
NIK

1

要在Windows Basic中重命名所有不带扩展名的文件,您可以执行以下操作:ren * *.jpg 由于该文件不带扩展名,请使用*,或者如果要将png更改为jpg,请使用ren *.png *.jpg


0

rename

不知道它可以重命名不带扩展名的文件(我现在在Windows 7上)


1
可以,但是它还会重命名目录,并且没有办法告诉它在子目录中递归工作(至少在Ubuntu上具有该版本)。
米罗德

我至少知道两个不同的命令rename,一个是util-linux-ng中包含的C程序,另一个是我们大学的Debian机器上的Perl程序(由Wall本人)。实际上,两者都没有递归。
Boldewyn
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.