Bash脚本删除目录中多个文件名末尾的'x'字符数量?

时间:2013-07-19 16:53:13

标签: linux bash unix sed

我在目录(/path/to/local)中有一个文件名列表。我想从所有这些文件名中删除一定数量的字符。

示例文件名:

iso1111_plane001_00321.moc1
iso1111_plane002_00321.moc1
iso2222_plane001_00123.moc1

在每个文件名中,我希望删除文件扩展名之前的最后5个字符。

例如:

iso1111_plane001_.moc1
iso1111_plane002_.moc1
iso2222_plane001_.moc1

我相信这可以使用sed完成,但我无法确定确切的编码。有点像...

for filename in /path/to/local/*.moc1; do
    mv $filname $(echo $filename | sed -e 's/.....^//');
done

......但这不起作用。很抱歉,如果我选择了sed选项,我就没有多少经验。

3 个答案:

答案 0 :(得分:6)

 mv $filname $(echo $filename | sed -e 's/.....\.moc1$//');

 echo ${filename%%?????.moc1}.moc1

%%是一个bash内部运算符...

答案 1 :(得分:1)

sed命令适用于您提供的所有示例。

sed -e 's/\(.*\)_.*\.moc1/\1_.moc1/'

但是,如果您只是想要“在文件名中的最后一个扩展名之前删除5个字符”这个命令就是您想要的:

sed -e 's/\(.*\)[0-9a-zA-Z]\{5\}\.\([^.]*\)/\1.\2/'

您可以在脚本中实现此功能,如下所示:

for filename in /path/to/local/*.moc1; do

    mv $filename "$(echo $filename | sed -e 's/\(.*\)[0-9a-zA-Z]\{5\}\.\([^.]*\)/\1.\2/')";

done

第一个命令解释

第一个sed命令的工作原理是抓取所有字符,直到第一个下划线:\(.*\)_

然后它会丢弃所有字符,直到找到.moc1.*\.moc1

然后它将它找到的文本替换为它首先在括号内抓取的所有内容:/\1

最后在最后添加.moc1扩展名并结束正则表达式:.moc1/

第二个命令说明

第二个sed命令首先抓取所有字符:\(.*\)

然后它被迫停止抓取字符,以便它可以丢弃五个字符,或者更具体地说,丢弃范围为0-9,a-z和A-Z的五个字符:[0-9a-zA-Z]\{5\}

然后点'.'字符标记最后一个扩展名:\.

然后它会查找所有非点字符。这可以确保我们抓住最后扩展程序:\([^.]*\)

最后,它用第一个和第二个捕获组替换所有文本,用.字符分隔,然后结束正则表达式:/\1.\2/

答案 2 :(得分:0)

这可能适合你(GNU sed):

sed -r 's/(.*).{5}\./\1./' file