如果文件名在Bash中具有前缀,则在句点之前删除字符

时间:2009-11-16 11:39:40

标签: bash sed rename

我有一个如下所示的目录:

pages/
    folder1/
        folder1.filename1.txt
        folder1.filename2.txt
    folder2/
        folder2.filename4.txt
        folder2.filename5.txt
    folder3/
        filename6.txt

我希望它看起来像这样:

pages/
    folder1/
        filename1.txt
        filename2.txt
    folder2/
        filename3.txt
        filename4.txt
    folder3/
        filename5.txt

使用ls * | sed -e s/^[^.]*.// > /tmp/filenames.txt我收到一个包含以下内容的文件:

filename1.txt
filename2.txt
filename3.txt
filename4.txt
txt

如何告诉sed 忽略[filename].[suffix]格式的文件名,只查看[foldername].[filename].[suffix]格式的文件名?

最终脚本(正如所指出的,find命令会简化一些事情,但这很有效):

for folder in $(ls .)
do
    if test -d $folder
    then
        pushd $folder
                ls * | sed 's/.*\.\(.*\..*\)/\1/' > /tmp/filenames.txt
                ls * > /tmp/current.txt

                exec 3</tmp/current.txt
                exec 4</tmp/filenames.txt

                while read file <&3; read name <&4;
                do
                    mv "$file" "$name"
                done

                rm /tmp/current.txt
                rm /tmp/filenames.txt
        popd
    else
        echo $folder "not a directory"
    fi
done

exit 0

此页面现在是社区维基。您可以在下方添加更优雅的解决方案:

for folder in $(ls .)
do 
     something better

3 个答案:

答案 0 :(得分:3)

尝试一下:

sed 's/.*\.\(.*\..*\)/\1/'

你应该真的使用find然后你不需要检查“-d folder”或临时文件和execs或while循环。

您可以使用进程替换来避免临时文件:

while read line
do
    echo $line
done < <(ls)

另一个感兴趣的项目:您的系统可能已经有一个名为renameprename的Perl脚本,它将使用正则表达式重命名文件。

答案 1 :(得分:2)

您无需使用sed

ls * > /tmp/current.txt
exec 3</tmp/current.txt
while read file <&3;
do
    replacement=${file#${folder}.}
    if [ "$replacement" != "txt" ] ; then
        mv "$file" "$replacement"
    fi
done

答案 2 :(得分:0)

使用以下正则表达式:

/\A(.\*?\\.){2,2}.+\Z/