2014-10-21 3 views
0

Я пытаюсь написать сценарий bash, который конвертирует все имена файлов в нижний регистр, но у меня есть проблема, потому что это не работает для одного случая.Создание сценария bash для изменения имен файлов в нижнем регистре

Если у вас есть file1 и FILE1, и вы будете использовать его на FILE1, он заменит письмо file1.

#!/bin/bash 

testFILE="" 
FLAG="1" 

for FILE in * 
do 
testFILE=`echo FILE | tr '[A-Z]' '[a-z]'` 

    for FILE2 in * 
    do 
     if [ `echo $testFILE` = `echo $FILE2` ] 
     then 
     FLAG="0" 
     fi 
    done 


    if [ $FLAG = "1" ] 
    then 
    mv $FILE `echo $FILE | tr '[A-Z]' '[a-z]'` 
    fi 

FLAG="1" 

done 
+1

Вы можете использовать 'mv -i' для запроса перед перезаписью и/или использовать' if [[-e "$ testFILE"]]; затем ... ', чтобы проверить, существует ли файл уже. –

ответ

4

Похоже

testFILE=`echo FILE | tr '[A-Z]' '[a-z]'` 

должен быть

testFILE=`echo "$FILE" | tr '[A-Z]' '[a-z]'` 

Переписывание сценарий, чтобы исправить некоторые другие мелкие вещи

#!/bin/bash 

testFILE= 
FLAG=1 

for FILE in *; do 
    testFILE=$(tr '[A-Z]' '[a-z]' <<< "$FILE") 

    for FILE2 in *; do 
    if [ "$testFILE" = "$FILE2" ]; then 
     FLAG=0 
    fi 
    done 

    if [ $FLAG -eq 1 ]; then 
    mv -- "$FILE" "$(tr '[A-Z]' '[a-z]' <<< "$FILE")" 
    fi 

    FLAG=1 
done 
  • Quote переменных для предотвращения софистики ("$FILE" вместо $FILE)
  • Обычно предпочтительнее использовать $() вместо тильды
  • Не используйте сравнение строк, где вы не должны
  • Используйте -- разграничить аргументы в команды, которые его принимают (чтобы предотвратить обработку файлов, таких как -file)
  • По соглашению вы должны использовать только имена переменных капитала для переменных среды, хотя я сохранил их выше.
  • Трубы против здесь струны (<<<) здесь не имеет значения, но <<< немного быстрее и вообще безопаснее.

Хотя более просто, я думаю, что вы хотите

#!/bin/bash 

for file in *; do 
    testFile=$(tr '[A-Z]' '[a-z]' <<< "$file") 
    [ -e "$testFile" ] || mv -- "$file" "$testFile" 
done 

Или на большинстве современных mv реализаций (технически не Posix)

#!/bin/bash 

for file in *; do 
    mv -n -- "$file" "$(tr '[A-Z]' '[a-z]' <<< "$file")" 
done 

С man страницы

-n, --no-clobber 
     do not overwrite an existing file 
+1

... или даже проще: '' $ {file ,,} "'. – jasonwryan

+0

@ jasonwryan Да, но только в bash 4+ – BroSlow

0

Ниже сценария:

find . -mindepth 1 -maxdepth 1 -print0 | while read -d '' filename 
do 
    if [ -e ${filename,,} ] 
    then 
    mv --backup ${filename} ${filename,,} 2>/dev/null 
     # create a backup of the desination only if the destination already exist 
     # suppressing the error caused by moving the file to itself 
    else 
    mv ${filename} ${filename,,} 
    fi 
done 

может выполнить эту работу за вас.

Преимущества этого сценария

  1. Он разбирает файлы, содержащие символы новой строки.
  2. Он избегает запроса, выполняя выборочное назначение резервного копирования, которое уже существует.
Смежные вопросы