在Linux中删除文件名的10个字符
我刚从服务器下载了大约600个文件,需要从文件名中删除最后11个字符(不包括扩展名)。我使用Ubuntu,我正在搜索一个命令来实现这一点 一些例子如下:在Linux中删除文件名的10个字符,linux,shell,ubuntu,file-rename,batch-rename,Linux,Shell,Ubuntu,File Rename,Batch Rename,我刚从服务器下载了大约600个文件,需要从文件名中删除最后11个字符(不包括扩展名)。我使用Ubuntu,我正在搜索一个命令来实现这一点 一些例子如下: aarondyne\u kh2\u第13次斗争或1250556383.mus应重命名为aarondyne\u kh2\u第13次斗争或.mus aarondyne_kh2_darknessofunknow_1250556659.mp3应重命名为aarondyne_kh2_darknessofunknow.mp3 在我这样做之后,似乎可能存在一些
aarondyne\u kh2\u第13次斗争或1250556383.mus
应重命名为aarondyne\u kh2\u第13次斗争或.mus
aarondyne_kh2_darknessofunknow_1250556659.mp3
应重命名为aarondyne_kh2_darknessofunknow.mp3
在我这样做之后,似乎可能存在一些重复项,但如果命令无法完成并告诉我重复项是什么,我总是可以手动删除这些重复项。不是最漂亮的,但非常简单:
echo "$filename" | sed -e 's!\(.*\)...........\(\.[^.]*\)!\1\2!'
您仍然需要编写脚本的其余部分,但它非常简单。尝试使用
重命名
命令。它允许您基于正则表达式重命名文件:
以下几行应该适合您:
rename 's/_\d+(\.[a-z0-9A-Z]+)$/$1/' *
将发生以下更改:
aarondyne_kh2_13thstruggle_or_1250556383.mus renamed as aarondyne_kh2_13thstruggle_or.mus
aarondyne_kh2_darknessofunknow_1250556659.mp3 renamed as aarondyne_kh2_darknessofunknow.mp3
您可以通过指定-n
标志来检查重命名
将执行的操作,如下所示:
rename -n 's/_\d+(\.[a-z0-9A-Z]+)$/$1/' *
有关如何使用rename
的更多信息,只需通过以下方式打开手册页:man rename
单程:
您会得到一个文件列表,每行一个(通过ls
maybe),然后:
这将打印mv a b
命令
e、 g
要执行,只需通过管道将其连接到|sh
我假定您的文件名中没有空格。此脚本假定每个文件只有一个扩展名。例如,它会将“foo.something.mus”重命名为“foo.mus”。要保留所有扩展名,请从循环体的第一行中删除一个哈希标记(#)。它还假设每个文件名的底部至少有12个字符,因此删除11个字符不会留下空名称
find . -type f -exec sh -c 'mv {} `echo -n {} | sed -E -e "s/[^/]{10}(\\.[^\\.]+)?$/\\1/"`' ";"
for f in *; do
ext=${f##*.}
new_f=${base%???????????.$ext}
if [ -f "$new_f" ]; then
echo "Will not rename $f, $new_f already exists" >&2
else
mv "$f" "$new_f"
fi
done
注意:我的rename版本(stock fedora 18!)没有标志
-n
,通常工作方式不同。特别是,它不支持正则表达式,只支持globs。@JonasWielicki感谢您的提示。我在我的Ubuntu12.10桌面版上测试了答案,所以它至少可以解决最初的问题。非常感谢。这对我有帮助!。。。哦,你只需删除数字,就可以用\d+
获取所有文件的名称,这比解析ls
的输出更安全;看有趣的。我知道,例如sed-e s/anton/berta
用berta
替换anton
,使用s
替换。你的语法遗漏了前斜杠!那么[^.]
是做什么的呢?是否要排除所有字符?。我知道人sed
。哦,
现在是分隔符,因为它更适合于文件名,所以您可以搜索…
,并将其替换为零(\1\2
)?再加上一个用于简单设计的分隔符。您如何知道在没有扩展名的情况下从末尾开始?我知道了,man,\1重复第一个模式(.*),而\2重复第二个模式(文件扩展名在点之后)。这两个点都是循环,因为*。点是任何字符,并且不可见,因为它们不出现在replace
中。我爱死你了!我喜欢简短的语法,所以加上1。你能解释一下你做了什么吗?您替换了所有字符,但没有替换。([^\\.]
)什么都没有(\\1
)?sed如何知道从结尾开始,但不包括扩展?
find . -type f -exec sh -c 'mv {} `echo -n {} | sed -E -e "s/[^/]{10}(\\.[^\\.]+)?$/\\1/"`' ";"
for f in *; do
ext=${f##*.}
new_f=${base%???????????.$ext}
if [ -f "$new_f" ]; then
echo "Will not rename $f, $new_f already exists" >&2
else
mv "$f" "$new_f"
fi
done