重命名文件扩展名而不指定

发布于 2024-11-08 03:49:46 字数 641 浏览 0 评论 0原文

我正在创建一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

花开半夏魅人心 2024-11-15 03:49:46
  • 始终在变量替换周围使用双引号,例如 echo "$FILE" 而不是 echo $FILE。如果没有双引号,shell 会扩展变量值中的空格和通配符 (\[*?)。 (在某些情况下,您不需要引号,有时您确实需要分词,但这是为了将来的课程。)
  • 我不确定您想用 sed 做什么,但无论它是什么,我确信它在 shell 中是可行的。
    • 检查$FILE是否包含点:case "$FILE" in *.*) echo yes;; *)回显否;; esac
    • 要从 $FILE 中删除最后一个扩展名:${FILE%.*}。例如,如果 $FILEfile1.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
  • Always use double quotes around variable substitutions, e.g. echo "$FILE" and not echo $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.)
  • I'm not sure what you're trying to do with sed, but whatever it is, I'm sure it's doable in the shell.
    • To check if $FILE contains a dot: case "$FILE" in *.*) echo yes;; *) echo no;; esac
    • To strip the last extension from $FILE: ${FILE%.*}. For example, if $FILE is file1.txt.foo, this produces file1.txt. More generally, ${FILE%SOME_PATTERN} expands to $FILE with a the shortest suffix matching SOME_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, the X needs to be at the beginning, because the problematic operators begin with a -: [ "X$TEMP" == "X" ].
  • If a file name begins with a -, 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".
  • This is very minor, but a common (not universal) convention is to use capital letters for environment variables and lowercase letters for internal script variables.
  • Since you're using only standard shell features, you can start the script with #!/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.

#!/bin/sh
ext="$1"; shift
for file in "$@"; do
  base="${file%.*}"
  mv -- "$file" "$base.$ext"
done
段念尘 2024-11-15 03:49:46

不完全是您要问的问题,但请查看 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.

小…楫夜泊 2024-11-15 03:49:46

用途:用于*.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

眼前雾蒙蒙 2024-11-15 03:49:46

对我来说这很有效,

for FILE in `ls`
do
NEW_FILE=${FILE%.*}
NEW_FILE=${NEW_FILE}${EXT}
done

我只是想告诉一下 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

for FILE in `ls`
do
NEW_FILE=${FILE%.*}
NEW_FILE=${NEW_FILE}${EXT}
done

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"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文