2010-12-22 126 views
37

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

我发现

rename .old .new *.old 

替代.old扩展到.new

此外,我想在子文件夹中的文件做到这一点。

回答

59

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

重命名将通过替换的第一发生命名指定的文件...

它会很高兴做错误的事情,如c.txt.parser.y

下面是使用findbash一个解决方案:

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

请记住,如果文件名包含一个换行符,这将打破(罕见,但并非不可能)。

如果你有GNU发现,这是一个更坚实的解决方案:

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

对于`rename`的`util-linux-ng`版本,这是真的,但Perl脚本版本可以'重命名's/.txt $ //'* .txt` – 2010-12-22 15:34:06

+0

对于我重命名's/.txt $ //'* .txt不起作用 – rp101 2010-12-22 20:00:38

10

您可以显式传入一个空字符串作为参数。

rename .old '' *.old

并与子文件夹,find . -type d -exec rename .old '' {}/*.old \;{}是用find找到的条目的替代品,并且\;终止-exec之后给出的命令的参数列表。

1

对于子文件夹:

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

这可能会导致问题,如果有一个与中有空格的文件夹名称。 – robert 2010-12-22 13:38:34

15

我用这个:

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

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

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

这可以结合查找以便也做子文件夹。

1

鱼,你可以做

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

万一有帮助,这是我如何与zsh中做到这一点:

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

${x%pattern}结构中的zsh在消除了pattern最短occurence $x结束。这被抽象成一个功能:

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 
} 

用法:

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: ".") 
相关问题