关于bash:linux:删除多个文件的文件扩展名

Linux: remove file extensions for multiple files

我有许多扩展名为.txt的文件。如何删除Linux中多个文件的.txt扩展名?

我发现

1
rename .old .new *.old

替代.old扩展到.new

我还想为子文件夹中的文件执行此操作。


rename有点危险,因为根据其手册页:

rename will rename the specified files by replacing the first occurrence of...

它很乐意对像c.txt.parser.y这样的文件名做错误的事情。

这里有一个使用findbash的解决方案:

1
find -type f -name '*.txt' | while read f; do mv"$f""${f%.txt}"; done

请记住,如果文件名包含换行符(很少,但并非不可能),这将中断。

如果您找到了GNU,这是一个更可靠的解决方案:

1
find -type f -name '*.txt' -print0 | while read -d $'\0' f; do mv"$f""${f%.txt}"; done


我用这个:

1
find ./ -name"*.old" -exec sh -c 'mv $0 `basename"$0" .old`.new' '{}' \;


Rename的Perl版本可以删除如下扩展:

1
rename 's/\.txt$//' *.txt

这可以与"查找"结合使用,以便同时执行子文件夹。


可以显式地将空字符串作为参数传递。

rename .old '' *.old

以及子文件夹,find . -type d -exec rename .old '' {}/*.old \;{}代替了find中的条目,\;终止了在-exec之后发出的命令的arglist。


如果有帮助,下面介绍我如何使用zsh:

1
2
3
for f in ./**/*.old; do
    mv"${f}""${f%.old}"
done

zsh中的${x%pattern}构造消除了pattern$x末尾出现的最短时间。这里它抽象为一个函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function chgext () {
    local srcext=".old"
    local dstext=""
    local dir="."

    [["$#" -ge 1 ]] && srcext="$1"
    [["$#" -gt 2 ]] && dstext="$2" dir="$3" || dir="${2:-.}"

    local bname=''
    for f in"${dir}"/**/*"${srcext}"; do
        bname="${f%${srcext}}"
        echo"${bname}{${srcext}${dstext}}"
        mv"${f}""${bname}${dstext}"
    done
}

用途:

1
2
3
4
5
6
7
8
chgext
chgext src
chgext src dir
chgext src dst dir

Where `src` is the extension to find (default:".old")
      `dst` is the extension to replace with (default:"")
      `dir` is the directory to act on (default:".")

在鱼里,你可以

1
2
3
for file in *.old
      touch (basename"$file" .old).new
end


用于子文件夹:

1
2
3
for i in `find myfolder -type d`; do
  rename .old .new $i/*.old
done


在bash linux中执行

1
for i in *;do mv ${i} ${i/%.pdf/} ;done