如何使用bash脚本递归地从文件中删除特定扩展名

如何使用bash脚本递归地从文件中删除特定扩展名,bash,filenames,Bash,Filenames,我试图找到一个bash脚本,它将递归地查找扩展名为.bx的文件,并删除此扩展名。文件名没有特定格式(有些是带有“.”前缀的隐藏文件,有些文件名中有空格等),并且并非所有文件都有此扩展名 我不知道如何找到扩展名为.bx的每个文件(在我的cwd中或下面)并将其删除。谢谢你的帮助 假设您位于要执行此操作的文件夹中 find . -name '*.bx' -type f | while read NAME ; do mv "${NAME}" "${NAME%.bx}" ; done find . -n

我试图找到一个bash脚本,它将递归地查找扩展名为.bx的文件,并删除此扩展名。文件名没有特定格式(有些是带有“.”前缀的隐藏文件,有些文件名中有空格等),并且并非所有文件都有此扩展名


我不知道如何找到扩展名为.bx的每个文件(在我的cwd中或下面)并将其删除。谢谢你的帮助

假设您位于要执行此操作的文件夹中

find . -name '*.bx' -type f | while read NAME ; do mv "${NAME}" "${NAME%.bx}" ; done
find . -name "*.bx" -print0 | xargs -0 rename .bx ""
Bash 4+

shopt -s globstar
shopt -s nullglob
shopt -s dotglob

for file in **/*.bx
do
  mv "$file" "${file%.bx}"
done

用于*.bx中的blah;do mv${blah}${blah%%.bx}

这是另一个版本,它执行以下操作:

  • 根据
    cwd
    中及其下方的
    $old\u ext
    变量(现在设置为
    .bx
    )查找文件,并将其存储在
    $files
  • 将这些文件的扩展名替换为nothing(或根据当前设置为
    .xyz
    $new\u ext
    变量的新内容)
  • 脚本使用
    dirname
    basename
    分别查找文件路径和文件名

    #!/bin/bash
    
    old_ext=".bx"
    new_ext=".xyz"
    
    files=$(find ./ -name "*${old_ext}")
    
    for file in $files
    do
        file_name=$(basename $file $old_ext)
        file_path=$(dirname $file)
        new_file=${file_path}/${file_name}${new_ext}
    
        #echo "$file --> $new_file"
        mv "$file"    "$new_file"
    done
    

    额外:如何从文件名中删除任何扩展名

    find -maxdepth 1 -type f | sed 's/.\///g'| grep -E [.] | while read file; do mv $file ${file%.*}; done
    
    将从最后一个点开始切割,即pet.cat.dog-->pet.cat

    find -maxdepth 1 -type f | sed 's/.\///g'| grep -E [.] | while read file; do mv $file ${file%%.*}; done
    
    将从第一个点开始切割,即pet.cat.dog-->pet


    “-maxdepth 1”将操作限制到当前目录,“-type f”仅用于选择文件。Sed&grep组合用于仅拾取带点的文件名。“mv”命令中的百分比符号数将定义实际切割点。

    第1行“.”附近的语法错误。xargs:rename:退出,状态为255;中止
    “${NAME}”“${NAME%.bx}”
    更好。文件名可能包含空格!这太完美了,谢谢。环顾四周后,我相信您也可以使用find中的regex来完成它,即find-输入f-regex'.*\.bx$'|,同时读取i;执行mv“$i”“${i%%.bx}”;doneDoes不为我工作(没有效果)。Linux(centos 5.5)上提供的
    rename
    版本不支持正则表达式。请参阅Raghuram的答案以获得有效的解决方案。似乎取决于当时的版本-man rename为我提供了“perl v5.10.1”(在Ubuntu 10.04.1上)对不起,我应该提到我使用的是OS X,不幸的是,它没有随rename一起提供。你的解决方案对linux用户来说很不错。忘了提一下,在OS X上运行这个。tylerl的解决方案效果很好。在Mac OS X上,你显然需要明确指定起始目录:
    find-maxdepth 1-读取文件时键入f | sed's/\///g'| grep-E[.]|;do mv$file${file%.*};完成
    (注意
    查找后的
    )。
    find -maxdepth 1 -type f | sed 's/.\///g'| grep -E [.] | while read file; do mv $file ${file%%.*}; done