重命名文件扩展名而不指定
我正在创建一个 bash shell 脚本,它将重命名文件扩展名,而无需指定旧的文件扩展名。如果我在 Linux 的终端中输入“change foo *”,它会将所有文件扩展名更改为 foo。
假设我有四个文件:“file1.txt”、“file2.txt.txt”、“file3.txt.txt.txt”和“file4”。
当我运行命令时,文件应如下所示:“file1.foo”,“file2.txt.foo”,“file3.txt.txt.foo”和“file4.foo”
有人可以查看我的代码并更正它。如果有人能为我实现这个,我也将不胜感激。
#!/bin/bash
shift
ext=$1
for file in "$@"
do
cut=`echo $FILE |sed -n '/^[a-Z0-9]*\./p'`
if test "${cut}X" == 'X'; then
new="$file.$ext"
else
new=`echo $file | sed "s/\(.*\)\..*/\1.$ext/"`
fi
mv $file $new
done
exit
I am creating a bash shell script that will rename a file extension without having to specify the old file extension name. If I enter "change foo *" to the Terminal in Linux, it will change all file extension to foo.
So lets say I've got four files: "file1.txt", "file2.txt.txt", "file3.txt.txt.txt" and "file4."
When I run the command, the files should look like this: "file1.foo", "file2.txt.foo", "file3.txt.txt.foo" and "file4.foo"
Can someone look at my code and correct it. I would also appreciate it if someone can implement this for me.
#!/bin/bash
shift
ext=$1
for file in "$@"
do
cut=`echo $FILE |sed -n '/^[a-Z0-9]*\./p'`
if test "${cut}X" == 'X'; then
new="$file.$ext"
else
new=`echo $file | sed "s/\(.*\)\..*/\1.$ext/"`
fi
mv $file $new
done
exit
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
echo "$FILE"
而不是echo $FILE
。如果没有双引号,shell 会扩展变量值中的空格和通配符 (\[*?
)。 (在某些情况下,您不需要引号,有时您确实需要分词,但这是为了将来的课程。)$FILE
是否包含点:case "$FILE" in *.*) echo yes;; *)回显否;; esac
$FILE
中删除最后一个扩展名:${FILE%.*}
。例如,如果$FILE
是file1.txt.foo
,则会生成file1.txt
。更一般地说,${FILE%SOME_PATTERN}
扩展为$FILE
,并删除匹配SOME_PATTERN
的最短后缀。如果没有匹配的后缀,它将扩展为$FILE
不变。变体${FILE%%SOME_PATTERN}
会去除最长的后缀。同样,${FILE#SOME_PATTERN}
和${FILE##SOME_PATTERN}
去除后缀。test "${TEMP}X" == 'X'
很奇怪。这看起来像是过去的一个被遗忘的把戏。正常的编写方式是[ "$TEMP" = "" ]
或[ -z "$TEMP" ]
。使用==
代替=
是 bash 扩展。如果$TEMP
看起来像一个运算符,曾经有一些有缺陷的 shell 可能会错误地解析命令,但这些已经走上了恐龙的道路,即使如此,X
需要位于开头,因为有问题的运算符以-
开头:[ "X$TEMP" == "X" ]
。-
开头,mv
会认为这是一个选项。使用--
表示“就是这样,没有更多选项,后面的都是操作数”:mv -- "$FILE" "$NEW_FILE"
。#!/bin/sh
启动脚本(当然,#!/bin/bash
也可以) 。exit
是没有用的。应用所有这些,这就是生成的脚本。
echo "$FILE"
and notecho $FILE
. Without double quotes, the shell expands whitespace and glob characters (\[*?
) in the value of the variable. (There are cases where you don't need the quotes, and sometimes you do want word splitting, but that's for a future lesson.)$FILE
contains a dot:case "$FILE" in *.*) echo yes;; *) echo no;; esac
$FILE
:${FILE%.*}
. For example, if$FILE
isfile1.txt.foo
, this producesfile1.txt
. More generally,${FILE%SOME_PATTERN}
expands to$FILE
with a the shortest suffix matchingSOME_PATTERN
stripped off. If there is no matching suffix, it expands to$FILE
unchanged. The variant${FILE%%SOME_PATTERN}
strips the longest suffix. Similarly,${FILE#SOME_PATTERN}
and${FILE##SOME_PATTERN}
strip a suffix.test "${TEMP}X" == 'X'
is weird. This looks like a misremembered trick from the old days. The normal way of writing this is[ "$TEMP" = "" ]
or[ -z "$TEMP" ]
. Using==
instead of=
is a bash extension. There used to be buggy shells that might parse the command incorrectly if$TEMP
looked like an operator, but these have gone the way of the dinosaur, and even then, theX
needs to be at the beginning, because the problematic operators begin with a-
:[ "X$TEMP" == "X" ]
.-
,mv
will think it's an option. Use--
to say “that's it, no more options, whatever follows is an operand”:mv -- "$FILE" "$NEW_FILE"
.#!/bin/sh
(but#!/bin/bash
works too, of course).exit
at the end of the script is useless.Applying all of these, here's the resulting script.
不完全是您要问的问题,但请查看 perl
rename
实用程序。非常强大!man rename
是一个好的开始。Not exactly what you are asking about, but have a look at the perl
rename
utility. Very powerful!man rename
is a good start.用途:用于*.gif文件;执行 mv $file ${file%.gif}.jpg;完成
或参见如何重命名多个文件< /a>
Use: for file in *.gif; do mv $file ${file%.gif}.jpg; done
Or see How to rename multiple files
对我来说这很有效,
我只是想告诉一下
NEW_FILE=${FILE%.*}
。这里 NEW_FILE 获取文件名作为输出。您可以随意使用它。
我在 bash 中使用
uname -a = "Linux 2.4.20-8smp #1 SMP Thu Mar 13 17:45:54 EST 2003 i686 i686 i386 GNU/Linux"
进行了测试For me this worked
I just want to tell about
NEW_FILE=${FILE%.*}
.Here NEW_FILE gets the file name as output. You can use it as you want.
I tested in bash with
uname -a = "Linux 2.4.20-8smp #1 SMP Thu Mar 13 17:45:54 EST 2003 i686 i686 i386 GNU/Linux"