使用 shell 脚本更改文件的扩展名
Posted
技术标签:
【中文标题】使用 shell 脚本更改文件的扩展名【英文标题】:Change extension of file using shell script 【发布时间】:2012-03-24 08:36:16 【问题描述】:如何将目录中所有 *.dat 文件的扩展名更改为 *.txt。 Shell 脚本应将目录名称作为参数。能 将多个目录作为参数。打印命令日志 导致带有日期和时间戳的附加模式。
【问题讨论】:
这是一道作业题吗?它应该被相应地标记。 如果不是,这是订单吗?哈哈 How do I rename the extension for a batch of files?的可能重复 【参考方案1】:Batch File Rename By File Extension in 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
【讨论】:
mv $file $file%.dat.txt # 知道你的 shell 内置 cruft 为什么不's/\.htm$/\.html/'
@Kaz,最好使用$file%%<EXT>
,因为可能有all.html.files.tar.gz
之类的东西
@Kaz $file %.dat 来自 bash,我不能使用 bash。 Pben 的答案更具交叉兼容性,这通常是我所需要的。
@SebastianGodelet 当 PAT 匹配固定长度的内容时,$VAR%PAT
和 $VAR%%PAT
之间没有区别,例如文字文本 .dat
。如果您的<EXT>
只是.html
,则无论%
还是%%
,它都不会匹配all.html.files.tar.gz
。【参考方案2】:
#!/bin/bash
for d in $*; do
for f in $(ls $d/*.dat); do
echo $(date) $(mv -v $f $f%.dat.txt)
done
done
在运行脚本时应该由shell完成输出重定向
省略参数有效性检查
【讨论】:
【参考方案3】:简单脚本:
#!/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 循环在 $@
上循环,即传递的命令行参数。
【讨论】:
【参考方案4】:按照 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;
【讨论】:
【参考方案5】:脚本,首先查找给定扩展名的名称。 它从名称中删除扩展名。然后添加反斜杠() 用于终端识别。
然后执行“mv”命令。 这里的“.temp”文件夹用于向用户隐藏进程, 在 GUI 中。
#!/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”文件夹被删除。
【讨论】:
【参考方案6】:票数最高的答案对我来说并不适用。我可能做错了什么。我的场景是尝试创建一个具有原始名称但附加日期的文件,并将扩展名从 .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”命令。
【讨论】:
我在投票最多的答案中遇到了同样的问题,但是,投票最多的答案更简洁,并为我提供了足够的细节以使其发挥作用。【参考方案7】:以下命令将文件扩展名.c
更改为.h
find . -depth -name "*.c" -exec sh -c 'dname=$(dirname ) && fname=$(basename .c) && mv $dname/$fname.h' ";"
【讨论】:
【参考方案8】:要重命名(更改扩展名)我在 epub 文件上的所有 html 文件,我使用以下命令行:
find . -name "*.html*" -exec rename -v 's/\.html$/\.epub/i' \;
【讨论】:
【参考方案9】:Bash 可以完成所有繁重的工作,例如提取扩展名并标记新的扩展名。例如:
for file in $1/*.dat ; do mv "$file" "$file%.*.txt" ; done
【讨论】:
欢迎来到 Stack Overflow!虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。 这是一个 bash 解决方案,而 OP 要求提供一个 shell 解决方案。不适用于 POSIX 环境。以上是关于使用 shell 脚本更改文件的扩展名的主要内容,如果未能解决你的问题,请参考以下文章