我正在创建一个 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
最佳答案
- 始终在变量替换周围使用双引号,例如
echo "$FILE"
而不是echo $FILE
。如果没有双引号,shell 会扩展变量值中的空格和 glob 字符 (\[*?
)。 (有些情况下您不需要引号,有时您确实需要分词,但那是为了以后的类(class)。) - 我不确定您要用 sed 做什么,但不管它是什么,我确信它在 shell 中是可行的。
- 检查
$FILE
是否包含点:case "$FILE"in *.*) echo yes;; *) echo 没有;; 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"
。 - 这是非常小的,但一个常见的(不是通用的)约定是对环境变量使用大写字母,对内部脚本变量使用小写字母。
- 因为您只使用标准的 shell 功能,您可以使用
#!/bin/sh
启动脚本(但是#!/bin/bash
也可以,当然)。
脚本末尾的 exit
没有用。
应用所有这些,这是生成的脚本。
#!/bin/sh
ext="$1"; shift
for file in "$@"; do
base="${file%.*}"
mv -- "$file" "$base.$ext"
done
关于bash - 重命名文件扩展名而不指定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6068733/