使用Shell脚本更改文件扩展名

23
如何将目录中所有 *.dat 文件的扩展名更改为 *.txt。Shell 脚本应该将目录名称作为参数。可以将多个目录作为参数。以追加模式打印带日期和时间戳的命令结果日志。

这是一道作业题吗?请给它打上相应的标签。 - William Pursell
5
不是的话,这是一道命令吗?哈哈 - salezica
可能是如何为一批文件重命名扩展名?的重复问题。 - jww
10个回答

42

Bash可以完成所有繁重的工作,例如提取扩展名并添加新扩展名。例如:

for file in $1/*.dat ; do mv "$file" "${file%.*}.txt" ; done

2
欢迎来到Stack Overflow!虽然这段代码片段可能解决了问题,但包括解释真的有助于提高您的帖子质量。请记住,您正在为未来的读者回答问题,而这些人可能不知道您提出代码建议的原因。 - Ferrybig
这是一个 bash 的解决方案,而原帖要求的是 shell 的解决方案。在 POSIX 环境下无法运行。 - Dunatotatos

21

在Unix中按文件扩展名进行批量文件重命名

# change .htm files to .html
for file in *.htm ; do mv $file `echo $file | sed 's/\(.*\.\)htm/\1html/'` ; done

# change .html files to .htm
for file in *.html ; do mv $file `echo $file | sed 's/\(.*\.\)html/\1htm/'` ; done

#change .html files to .shtml
for file in *.html ; do mv $file `echo $file | sed 's/\(.*\.\)html/\1shtml/'` ; done

#change .html files to php
for file in *.html ; do mv $file `echo $file | sed 's/\(.*\.\)html/\1php/'` ; done

所以 ==>

# change .dat files to .txt
for file in *.dat ; do mv $file `echo $file | sed 's/\(.*\.\)dat /\1txt/'` ; done

22
将$file重命名为${file%.dat}.txt。 #了解你的shell内置垃圾。 - Kaz
为什么不使用 's/\.htm$/\.html/' - Sebastian
2
@Kaz,最好使用${file%%<EXT>},因为有些文件名可能会像all.html.files.tar.gz - Sebastian
@Kaz ${file %.dat} 是来自 Bash,但我无法使用 Bash。Pben的答案更具跨平台兼容性,这通常是我所需要的。 - DKATyler
@user1361991 ${VAR%PATTERN} 是 POSIX 标准的 shell 语法。 - Kaz
1
@SebastianGodelet 当PAT匹配固定长度的内容时,例如文字“.dat”,${VAR%PAT}${VAR%%PAT}之间没有区别。如果你的<EXT>只是“.html”,无论使用%还是%%,它都不会匹配到“all.html.files.tar.gz”。 - Kaz

8
#!/bin/bash
for d in $*; do
    for f in $(ls $d/*.dat); do
        echo $(date) $(mv -v $f ${f%.dat}.txt)
    done
done

运行脚本时,输出重定向应由shell完成

省略参数有效性检查


2

简单的脚本:

#!/bin/bash

if [ $# -lt 2 ] then
    echo "Usage `basename $0` <any number of directories space separated>"
    exit 85              # exit status for wrong number of arguments.
fi

for directories
do
    for files in $(ls $directories/*.dat); do
        echo $(date) $(mv -v $files ${files%.dat}.txt)
    done
done

默认情况下,第一个for循环会循环遍历$@,即传递的命令行参数。

1

为了将所有的html文件重命名为epub文件(更改扩展名),我使用以下命令行:

find . -name "*.html*" -exec rename -v 's/\.html$/\.epub/i' {} \;

rename 命令根据第一个参数指定的规则重命名所提供的文件名。要在 Ubuntu 中安装 rename 命令,请运行 sudo apt install rename - t98907

1

如果您的文件名包含空格,可以像以下方式使用双引号将变量括起来,遵循Pben的解决方案:

#remove the space in file name
#example file name:19-014-0100.mp3 .mp3
#result file name:19-014-0100.mp3
$ for file in *.mp3 ; 
    do target=`echo "$file" | sed 's/ //g'`;
    echo "$target"; 
    mv "$file" "$target"; 
done;

#remove the duplicate file extension in file name
#example file name:19-014-0100.mp3.mp3
#result file name:19-014-0100.mp3
$ for file in *.mp3 ; 
    do target=`echo "$file" | sed 's/\.mp3\.mp3$/.mp3/g'`;
    echo "$target"; 
    mv "$file" "$target"; 
done;

0

最高票答案对我并没有真正起作用。可能是我做错了什么。我的情况是尝试创建一个带有原始名称的文件,但附加了日期,并将扩展名从.xslx更改为.csv。这是对我有效的方法:

csvname=`echo $xlsx |sed 's/\.xlsx//'`"-$now"`echo $xlsx | sed 's/\(.*\.\)xlsx/\.csv/'`

因此,对于目录中所有没有日期附加的 .dat 文件,您可以运行类似以下的命令:

for i in *.dat
do mv $i `echo $i |sed 's/\.dat//'``echo $i | sed 's/\(.*\.\)dat/\.txt/'`
done

从上面可以看出,这段代码仅仅移除了文件扩展名:
echo $i |sed 's/\.dat//'

这个部分将 .dat 文件转换为 .txt 文件:

echo $i | sed 's/\(.*\.\)dat/\.txt/'

通过将它们挨在一起,将两个输出连接成文件名。就像这样:

mv [filename][.dat] [filename] + [.txt]

虽然我使用了STDOUT而不是'mv'命令。


我遇到了与最受欢迎的回答相同的问题,但是最受欢迎的回答更加简洁,并提供了足够的细节让我能够使其正常工作。 - DKATyler

0
以下是将文件扩展名从 .c 改为 .h 的命令:
find . -depth -name "*.c" -exec sh -c 'dname=$(dirname {}) && fname=$(basename {} .c) && mv {} $dname/$fname.h' ";"

0

递归地将js文件更改为cjs扩展名:

cd dist # where you place your .js
for file in $(find . -type f -name "*.js"); do mv "$file" "${file%.*}.cjs"; done

0

脚本首先查找给定扩展名的名称。 它从名称中删除扩展名。然后添加反斜杠(\)以标识终端。

然后执行“mv”命令。 在GUI中,使用“.temp”文件夹隐藏进程。

#!/bin/sh
if [ $# -ne 3 ] 
then
    echo "Usage:  ./script folder current_extension modify_extension"
    exit
fi
mkdir .temp
find $1 -name "*.$2" > .temp/output_1 && sed "s/$2//" .temp/output_1 > .temp/output_2 && sed -e "s/[ \t]/\\\ /g" .temp/output_2 > .temp/output_3
while read line
do
    mv -v "$line""$2" "$line""$3"
done < .temp/output_3
rm -rf .temp

输出文件保存在'.temp'文件夹内,之后将删除'.temp'文件夹。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接