Почему я могу просто выполнить команду в окне терминала, но в скрипте bash возникает ошибка? - PullRequest
0 голосов
/ 24 ноября 2011

Я организовывал свою музыкальную библиотеку в последнее время, и я стараюсь, чтобы все "выглядело" одинаково. Все мои песни должны выглядеть как 04 John Barleycorn.m4a, но некоторые из них, исходя из многодисковых наборов, выглядят как 2-04 John Barleycorn.m4a. Поэтому я сразу подумал: «Почему бы не написать сценарий bash для всей этой утомительной работы за меня?» Мало ли я знал, я бы потратил больше времени, пытаясь выяснить эту «ошибку», чем просто сделать это вручную. Только одно маленькое отличие: я бы не научился делать это вручную!

Итак, вот мой сценарий:

#!/bin/bash

filename="/tmp/fileout.txt"

find . -name '?-*.???' > $filename

cat $filename | while read line
do
    echo ${line:1}
    newname=$(echo ${line%\/*}/${line#*-})
    echo $newname
    #mv \"$line\" \"$newname\"
done

Это должно быть достаточно просто, верно? Он находит все файлы в многодисковом формате и помещает их в текстовый файл. Каждая строка затем читается, переформатируется и «перемещается» в новое местоположение / имя файла. (некоторые части закомментированы, так как я хочу убедиться, что все «хорошо выглядело» перед перемещением файлов) Однако, когда я впервые попробовал это (после того, как все «хорошо выглядело» и удалил # перед mv), Я продолжал получать

mv: target `Barleycorn.m4a"' is not a directory

и я думаю, что это потому, что пространства не ускользают. Я думал, что, заключив в кавычки, это решило бы это, но очевидно нет.

Но я постараюсь это исправить позже. Вот моя проблема с ошибками. Я хочу удалить первый символ (точку) в имени файла (просто пример ... Мне действительно не нужно , чтобы сделать это по любой причине):

line="./Traffic/Smiling Phases/04 John Barleycorn.m4a"
echo ${line:1}

отлично работает, набрав его в командной строке.

Но в bash-скрипте он отвечает:

/home/kyleowen/filerenamer.sh: 15: Bad substitution

Я уже много раз сталкивался с этой ошибкой при использовании ${var//foo/bar/} и других строковых операций в фигурных скобках.

Почему он это делает? Разве мой скрипт не выполняет все операции, как если бы они были в командной строке?

Мне бы очень понравился работающий скрипт bash, конечно ... но я в основном спрашиваю, почему я получаю ошибку Bad substitution при работе со строковыми операциями. Спасибо!

РЕДАКТИРОВАТЬ: Я нашел свою довольно смущающую ошибку ... никогда не упоминал, как я выполнял эти сценарии. Я выполнял их как sh test.sh вместо bash test.sh. Я предполагал, что sh выполнит их как оболочку вашего пользователя по умолчанию, но я предполагаю, что я не прав (или оболочкой по умолчанию не является bash).

Спасибо за советы по перенаправлению ввода! Я отправлю обратно то, что имею, когда получу что-то, что работает.

Ответы [ 2 ]

2 голосов
/ 24 ноября 2011

Попробуйте без обратной косой черты в командной строке mv?

mv "$line" "$newname"

Обратная косая черта заставляет mv искать файлы с буквенными двойными кавычками в имени файла.

2 голосов
/ 24 ноября 2011

Существует несколько несоответствий в цитировании:

while read line
do
     echo "${line:1}"
     newname="${line%\/*}/${line#*-}"
     echo "$newname"
     # mv "$line" "$newname"
done < <(find . -name '?-*.???')

В общем, совет: используйте перенаправление ввода вместо трубопровода в read

Причина: цикл while будет выполняться в подоболочке из-за канала

...