开发者

Renaming a file extension without specifying

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 "fi开发者_如何学Pythonle4.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


  • 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


Not exactly what you are asking about, but have a look at the perl rename utility. Very powerful! man rename is a good start.


Use: for file in *.gif; do mv $file ${file%.gif}.jpg; done

Or see How to rename multiple files


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"

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜