编写一个简单的脚本,可以自动重命名多个文件。例如,我们想将文件*001.jpg重命名为用户定义的字符串+001.jpg(例如:MyVacation20110725_001.jpg)。此脚本的用途是使数码相机照片具有一些有意义的文件名。
我需要编写一个Shell脚本来实现这个功能。有人能建议一下如何开始吗?
编写一个简单的脚本,可以自动重命名多个文件。例如,我们想将文件*001.jpg重命名为用户定义的字符串+001.jpg(例如:MyVacation20110725_001.jpg)。此脚本的用途是使数码相机照片具有一些有意义的文件名。
我需要编写一个Shell脚本来实现这个功能。有人能建议一下如何开始吗?
一个例子可以帮助你入门。
for f in *.jpg; do mv "$f" "$(echo "$f" | sed s/IMG/VACATION/)"; done
在这个例子中,我假设所有的图像文件都包含字符串IMG
,你想用VACATION
来替换它。
Shell会自动将*.jpg
展开成所有匹配的文件。
mv
的第二个参数(文件的新名称)是sed
命令替换IMG
为VACATION
的输出。
如果您的文件名包含空格,请注意"$f"
的表示法。您需要使用双引号来保留空格。
sed 's/foo/bar/' <<< "$f"
。意思是使用 sed 命令从一个变量 $f
中提取的字符串,并对其进行替换操作,将字符串中的 "foo" 替换为 "bar"。重定向操作符 <<<
用于将该字符串作为输入传递给 sed。 - glenn jackman*-1.0-SNAPSHOT.war
的文件更改为*.war
,像这样:for i in *.war; do mv ${i} \
echo ${i} | sed 's/-1.0-SNAPSHOT.war/.war/'`; done` - mikequentel${file//IMG/myVacation}
替换不符合POSIX标准。它无法与dash
一起使用。在Debian上,默认的sh
是dash
。当dash
遇到${file//IMG/myVacation}
时,会因为此语法不符合POSIX而失败并显示“Bad substitution”错误。 - Susam Palrename 's/^/MyVacation2011_/g' *.jpg
或者rename <pattern> <replacement> <file-list>
-bash:/usr/bin/rename:参数列表太长
。但我同意如果你有一个较小的列表会更好。 - TM.find
来规避:find . -name *.jpg -exec rename <pattern> <replacement> {} \;
这将为每个文件调用一次重命名。 - Erik Forsberg$<groupNumber>
进行替换。例如:rename 's/([^-]+)-([^.]+)/$2-$1/g' *
。模式 ^([^-]+)-([^.]+)
的意思是:从名称开头,捕获一个或多个不是 -
的字符,然后期望一个破折号,然后捕获一个或多个不是 .
的字符。$1
是第一个捕获,$2
是第二个。 - Eric Haynesfind . -name '*jpg' -exec bash -c 'echo mv $0 ${0/IMG/VACATION}' {} \;
'echo mv $0 ${0/IMG/VACATION}'
这部分是针对每个找到的文件实际运行的命令。因此,如果你保留 echo
,它只会回显将要执行的操作。删除 echo
命令以实际移动文件,例如 find . -name '*jpg' -exec bash -c 'mv $0 ${0/IMG/VACATION}' {} \;
。 - dmmdecho
,这样用户就知道它是否有效。 - Tungfor file in *.jpg ; do mv $file ${file//IMG/myVacation} ; done
假设所有的图像文件都包含字符串"IMG",您希望用"myVacation"替换"IMG"。
使用bash,您可以直接使用参数扩展来转换字符串。
例如:如果文件是IMG_327.jpg,则mv
命令将被执行,就像您执行mv IMG_327.jpg myVacation_327.jpg
一样。并且这将针对在目录中找到的每个与*.jpg
匹配的文件执行。
IMG_001.jpg -> myVacation_001.jpg
IMG_002.jpg -> myVacation_002.jpg
IMG_1023.jpg -> myVacation_1023.jpg
以此类推...
${file//IMG/myVacation}
替换不符合POSIX。它无法与dash
一起使用。在Debian上,默认的sh
是dash
。当dash
遇到${file//IMG/myVacation}
时,会因为此替换语法不符合POSIX而失败,并显示“Bad substitution”错误。 - Susam Palfind . -type f |
sed -n "s/\(.*\)factory\.py$/& \1service\.py/p" |
xargs -p -n 2 mv
eg 将当前工作目录中所有以“factory.py”结尾的文件重命名为以“service.py”结尾的名称。
解释:
在sed命令中,-n标志将抑制正常行为,在s///命令应用后不会回显输入到输出,s///上的p选项将强制写入输出,如果进行了替换。由于替换只会在匹配时进行,因此sed只会对以“factory.py”结尾的文件进行输出。
在s///替换字符串中,我们使用“&amp; ”将整个匹配字符串插入到替换中,后跟一个空格字符。由于这一点,我们的RE必须匹配整个文件名。在空格字符之后,我们使用“\1service.py”插入我们之前捕获的字符串“factory.py”之前的字符串,后跟“service.py”进行替换。因此,对于更复杂的转换,您将需要更改s///的参数(仍然与re匹配整个文件名)
示例输出:
foo_factory.py foo_service.py
bar_factory.py bar_service.py
xargs
和-n 2
,每次处理sed输出的两个分隔字符串,并将它们传递给mv(我还加入了-p选项,以便在运行此命令时更安全)。大功告成。注意:如果您面对更复杂的文件和文件夹情况,请参考此文章详细介绍了find(及其一些替代方法)。
cygwin
)中,其中某些解决方案所需的启用正则表达式的 replace
的 perl replace
不可用或难以获得。 - Domifor i in *001.jpg
do
echo "mv $i yourstring${i#*001.jpg}"
done
在正确使用之后,删除echo
。
使用#
进行参数替换时,只保留最后一部分,所以您可以更改其名称。
我不能对Susam Pal的答案进行评论,但如果你正在处理空格,我建议用引号括起来:
for f in *.jpg; do mv "$f" "`echo $f | sed s/\ /\-/g`"; done;
for file in *.jpg;
do
mv $file $somestring_${file:((-7))}
done
man bash
中查看"参数扩展"以更好地理解上述内容。