【发布时间】:2012-03-24 08:36:16
【问题描述】:
如何将目录中所有 *.dat 文件的扩展名更改为 *.txt。 Shell 脚本应将目录名称作为参数。能 将多个目录作为参数。打印命令日志 导致带有日期和时间戳的附加模式。
【问题讨论】:
-
这是一道作业题吗?它应该被相应地标记。
-
如果不是,这是订单吗?哈哈
如何将目录中所有 *.dat 文件的扩展名更改为 *.txt。 Shell 脚本应将目录名称作为参数。能 将多个目录作为参数。打印命令日志 导致带有日期和时间戳的附加模式。
【问题讨论】:
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
【讨论】:
's/\.htm$/\.html/'
${file%%<EXT>},因为可能有all.html.files.tar.gz之类的东西
${VAR%PAT} 和 ${VAR%%PAT} 之间没有区别,例如文字文本 .dat。如果您的<EXT> 只是.html,则无论% 还是%%,它都不会匹配all.html.files.tar.gz。
#!/bin/bash
for d in $*; do
for f in $(ls $d/*.dat); do
echo $(date) $(mv -v $f ${f%.dat}.txt)
done
done
在运行脚本时应该由shell完成输出重定向
省略参数有效性检查
【讨论】:
简单脚本:
#!/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 循环在 $@ 上循环,即传递的命令行参数。
【讨论】:
按照 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;
【讨论】:
脚本,首先查找给定扩展名的名称。 它从名称中删除扩展名。然后添加反斜杠() 用于终端识别。
然后执行“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”文件夹被删除。
【讨论】:
票数最高的答案对我来说并不适用。我可能做错了什么。我的场景是尝试创建一个具有原始名称但附加日期的文件,并将扩展名从 .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”命令。
【讨论】:
以下命令将文件扩展名.c更改为.h
find . -depth -name "*.c" -exec sh -c 'dname=$(dirname {}) && fname=$(basename {} .c) && mv {} $dname/$fname.h' ";"
【讨论】:
要重命名(更改扩展名)我在 epub 文件上的所有 html 文件,我使用以下命令行:
find . -name "*.html*" -exec rename -v 's/\.html$/\.epub/i' {} \;
【讨论】:
Bash 可以完成所有繁重的工作,例如提取扩展名并标记新的扩展名。例如:
for file in $1/*.dat ; do mv "$file" "${file%.*}.txt" ; done
【讨论】: