Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Linux中删除文件名的10个字符_Linux_Shell_Ubuntu_File Rename_Batch Rename - Fatal编程技术网

在Linux中删除文件名的10个字符

在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 在我这样做之后,似乎可能存在一些

我刚从服务器下载了大约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


在我这样做之后,似乎可能存在一些重复项,但如果命令无法完成并告诉我重复项是什么,我总是可以手动删除这些重复项。

不是最漂亮的,但非常简单:

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