有没有在Shell/Bash中可以根据正则表达式或其他标准来重命名文件夹中所有文件的快捷方式。我想要的是,在我的文档文件夹中,有一个命名约定为以下的100个文本文件:
<longdocumentidentifier>-doc-<counter>.txt.
我需要将所有文件按照上述规则重命名为:
doc-<counter>.txt
有没有一个一行代码的解决方案可以帮我解决上述问题?
我建议做类似于这样的事情:
for i in *-doc-*.txt; do mv "$i" "${i/*-doc-/doc-}"; done
${i/*-doc-/doc-}
将第一个出现的*-doc-
替换为doc-
。
如果你需要执行多个替换(参见评论1),你需要使用${var//Pattern/Replacement}
变体。如果你需要替换名称开头,你需要使用${var/#Pattern/Replacement}
,如果你需要替换结尾(即扩展名),你需要使用${var/%Pattern/Replacement}
形式。
更多细节请参见Shell Parameter Expansion(Shell参数扩展)。这种扩展仅适用于bash。
rename
命令,那么rename 's/^.*-doc-/doc-/' *.txt
应该可以解决问题。有一个prename
,允许您使用正则表达式:
prename 's/^.*-doc-(.*\.txt)$/doc-$1/' *.txt
使用选项 -n
进行模拟:
prename -n 's/^.*-doc-(.*\.txt)$/doc-$1/' *.txt
注意:在许多Linux发行版中,该实用程序被称为rename
。但并非所有Linux发行版都是这样的 - 因此,我使用与Perl附带的实用程序相同的规范名称。
如果您想递归地处理子目录,也可以使用以下方法:
find . -maxdepth N -type f -name "$pattern" | sed -e 'p' -E -e "s/$str1/$str2/g" | xargs -n2 mv
在自动支持扩展正则表达式的系统中,您可以省略-E
。sed: -e expression #2, char 33: unterminated \
s' command`。有什么建议吗? - Peter大多数Linux系统内置了重命名命令,例如,可以轻松完成此操作。
个人而言,我也更喜欢使用正则表达式,这就是为什么我已经携带着这个脚本很长时间了(阅读:自上世纪80年代末或90年代初以来):
#!/usr/bin/perl
($op = shift) || die "Usage: $0 expr [files]]\n";
if(!@ARGV)
{
@ARGV = <STDIN>;
chop(@ARGV);
}
for (@ARGV)
{
$was = $_;
eval $op;
die $@ if $@;
if ($was ne $_)
{
print "rename($was,$_)\n";
rename($was,$_);
}
}
当安装完成后,您可以执行以下操作:
script-name 's/.*-doc(.*).txt/doc$1.txt/' *.txt
mmv "*-doc-*" "doc-#2"
mmv命令代表“批量移动(mass move)”
for i in *; do mv "$i" ${i//\ /-}; done
。请注意,为了使其工作,我必须引用原始文件名。 - Richard Turnerfor i in *.sh; do mv $i ${i/.sh/}; done
。 - m3nda${i/.sh/}
会删除第一个匹配的.sh字符串。为确保您删除扩展名(我假设您想要这样做),您应该使用${i/%.sh/}
。 - Sorin*
来匹配被i/
替换的元素,所以我没有猜到%
的工作原理类似于正则表达式中的$1
匹配组。非常好,谢谢。 - m3nda/%
表示匹配字符串的后缀。 - Sorin/(.*).sh/$1/
时,$1是正则表达式中的一个占位符,可以帮助你节省一些代码。我只是评论了如何比较两种情况。我没有想到参数替换会使用其他字符来完成它的工作。抱歉 :-) 谢谢。 - m3nda