在Windows / DOS中,我可以说rename myfile.* yourfile.*
要更改名称但保留扩展名。在Linux上如何完成?
手册页仅建议如何更改扩展名,但这与我想要的相反。
奖励:
实际上,我想将照片的创建日期放入文件名中,以获得类似的信息20091231 2359 New Year.jpg
。恐怕我需要一些平凡的命令组合才能实现这一目标?
在Windows / DOS中,我可以说rename myfile.* yourfile.*
要更改名称但保留扩展名。在Linux上如何完成?
手册页仅建议如何更改扩展名,但这与我想要的相反。
奖励:
实际上,我想将照片的创建日期放入文件名中,以获得类似的信息20091231 2359 New Year.jpg
。恐怕我需要一些平凡的命令组合才能实现这一目标?
Answers:
这是奖金问题的答案。
我实际上想将照片的创建日期放入文件名中,以获得类似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
[...]
这是一个例子:
$ jhead -n%Y-%m-%d-%f New_year.jpg
New_year.jpg --> 2009-12-31-New_year.jpg
编辑:当然,要对一堆照片执行此操作,将类似于:
$ for i in *jpg; do jhead -n%Y-%m-%d-%f $i; done
要根据自己的喜好调整日期格式,请查看的输出date --help
,例如;它将列出可用的格式代码。
(jhead可在不同的系统上广泛使用。如果例如在Ubuntu或Debian上,只需键入sudo apt-get install jhead
以安装它即可。)
对于重命名部分,“重命名”程序将起作用。它与您在手册页中看到的示例相同,只是切换了一下。
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$
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
关键是,如果您看到了一个示例,该示例显示了如何使用正则表达式来修改文件名的一部分,那这就是您唯一需要的示例。扩展在UNIX文件系统上没有特殊的状态-它们只是文件名的一部分,恰好在.
字符之后。
mv "$file" yourfile"${file#myfile}"
。可在任何现代的Bourne式外壳(或任何POSIX外壳)上运行,但可能不适用于实际的Bourne外壳。
这是操纵文件名的几种其他方法
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
该参数扩展在mv
命令如下工作:
${f%.*}
-从中包含的字符串的末尾删除最短的匹配模式$f
,在这种情况下,删除最后一个点之后(包括最后一个点)的所有内容。单一的%
意思是“从头到尾最短”。
${f##*.}
-从中包含的字符串的开头删除最长的匹配模式$f
,在这种情况下,最后一个点之前(包括最后一个点)(包括所有其他点)也将全部删除。双#
(##
)表示“从头开始最长”。
因此,例如,如果$f
包含“ Foo.bar.baZ.jpg”:
echo "${f%.*}"
给
Foo.bar.baZ
和
echo "${f##*.}"
给
jpg
因此mv
,一旦展开,该命令将如下所示:
mv "Foo.bar.baZ.jpg" "before_partFoo.bar.baZafter_part.jpg"
Linux中没有文件扩展名。
使用正则表达式从文件名中剪切特定的子字符串并进行访问。
例:
实际场景:您正在从chm文件中提取html。Windows中的文件名不区分大小写,因此在Linux中,链接会断开。您有一个名为index.HTML的文件,但URL中的href =“ index.html”。因此,您的目标是调整文件名以使其匹配链接。
假设文件名包含在变量中:
FILENAME='index.HTML'
从3.0版开始,bash本身支持正则表达式,因此您不需要任何其他工具(例如grep / sed / perl等)即可执行字符串操作。以下示例说明了字符串中后端匹配的替换:
echo ${FILENAME/%\.HTML/.html}
匹配和替换字符串可以根据需要设置参数,这在编写脚本时提供了更大的灵活性。以下代码段实现了相同的目标:
match='\.HTML'
replacement='.html'
echo ${FILENAME/%$match/$replacement}
请查阅bash文档以获取更多信息。
这是另一个:
find -name "*.jpg" -printf '"%p" "%h/%TY%Tm%Td %TH%TM %f"\n' | while read -r f
do
eval "mv ${f}"
done
总是有不止一种方法来做到这一点。我将以下脚本命名为/ usr / local / bin / mrename。
然后在包含照片文件的脚本中,键入:mrename
脚本中还有一个可选的注释掉功能,用于缩放照片(使用ImageMagick)。
希望这对某些人有用。
#!/usr/bin/perl
#
# mrename files
#
#
use strict;
# if no 2 args, use defaults
my $dir = ".";
# read in path from command line
$dir = $ARGV[0] if ( defined( $ARGV[0] ) && $ARGV[0] ne "" );
# read in directory contents
opendir( DIR, $dir );
my @files = readdir( DIR );
closedir( DIR );
# rename and/or scale each file in directory
my $number_of_files = scalar( @files );
my $curfile = 0;
foreach my $file( @files ) {
# only rename and scale jpg/gif files
if ( $file =~ /\w+\.(jpg)$/ ) {
my $extension = $1;
$extension =~ tr/A-Z/a-z/;
my $full_filename = "$dir/$file";
# get stats on file- specifically the last modified time
(my $dev,my $ino,my $mode,my $nlink,my $uid,my $gid,my $rdev,my $size,
my $atime,my $mtime,my $ctime,my $blksize,my $blocks) = stat($full_filename);
# convert last-modified time from seconds to practical datetime terms
(my $sec,my $min,my $hour,my $mday,my $mon,my $year,my $wday,my $yday,
my $isdst) = localtime($mtime);
++$mon;
$year += 1900;
my $filecdate = sprintf( "m%04i%02i%02i_%02i%02i%02i.$extension", $year, $mon, $mday, $hour, $min, $sec );
my $full_newfilename = "$dir/$filecdate";
# to scale files, use imagemagick by using the command below instead of mv
#my $cmd = "convert $full_filename -resize $scale% $full_newfilename";
my $cmd = "mv $full_filename $full_newfilename";
system( $cmd );
# update percentage done
my $percent_done = sprintf( "%5.2lf", 100* (++$curfile) / $number_of_files );
print "\r$percent_done%";
}
}
print "\n";
您可以将-X/--keep-extension
选项与rename
(版本1.600)一起使用:
-X, --keep-extension
Save and remove the last extension from a filename, if there is any. The saved extension will be appended back to the filename at the end of the rest of the operations.
rename
适用于Homebrew的Mac和Linuxbrew的Linux(当然还有其他安装选项)。