Переименование расширения файла без указания - PullRequest
2 голосов
/ 20 мая 2011

Я создаю сценарий оболочки bash, который переименует расширение файла без необходимости указывать старое имя расширения файла.Если я введу «change foo *» для терминала в Linux, он изменит все расширение файла на 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

Ответы [ 4 ]

5 голосов
/ 20 мая 2011
  • Всегда используйте двойные кавычки вокруг переменных, например echo "$FILE", а не echo $FILE.Без двойных кавычек оболочка расширяет пробельные и глобальные символы (\[*?) в значении переменной.(Есть случаи, когда вам не нужны кавычки, а иногда вы хотите разделить слова, но это для будущего урока.)
  • Я не уверен, что вы пытаетесь делать с sed,но что бы это ни было, я уверен, что это выполнимо в оболочке.
    • Чтобы проверить, содержит ли $FILE точку: case "$FILE" in *.*) echo yes;; *) echo no;; 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 выглядел как оператор, но они пошли по пути динозавра, и даже тогда X должен быть в начале, потому что проблемные операторыначинаются с -: [ "X$TEMP" == "X" ].
  • Если имя файла начинается с -, mv будет считать, что это вариант.Используйте --, чтобы сказать «все, больше никаких опций, все, что следует за операндом»: mv -- "$FILE" "$NEW_FILE".
  • Это очень незначительно, но распространенное (не универсальное) соглашение - использовать заглавные буквыПеременные окружения и строчные буквы для внутренних переменных скрипта.
  • Поскольку вы используете только стандартные функции оболочки, вы можете запустить скрипт с #!/bin/sh (но, конечно, #!/bin/bash тоже работает).
  • exit в конце скрипта бесполезен.

Применяя все это, вот результирующий скрипт.

#!/bin/sh
ext="$1"; shift
for file in "$@"; do
  base="${file%.*}"
  mv -- "$file" "$base.$ext"
done
1 голос
/ 12 сентября 2011

Использование: для файла в * .gif;do mv $ file $ {file% .gif} .jpg;сделано

Или см. Как переименовать несколько файлов

1 голос
/ 20 мая 2011

Не совсем то, о чем вы спрашиваете, но посмотрите на утилиту perl rename. Очень могущественный! man rename - хорошее начало.

0 голосов
/ 20 мая 2011

Для меня это сработало

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"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...