#shell #zsh
Вопрос:
В следующей истории оболочки показаны две попытки переименования файлов, вторая попытка удалась. Но с первой попытки этого не произошло, и я понятия не имею, почему…
❯ ls
step-10.txt step-12.txt step-14.txt step-16.txt step-18.txt step-1.txt step-3.txt step-5.txt step-7.txt step-9.txt
step-11.txt step-13.txt step-15.txt step-17.txt step-19.txt step-2.txt step-4.txt step-6.txt step-8.txt
❯ for f in *.txt; do
newname=$(echo $f | sed 's/txt/md/')
mv $f $newname
done
zsh: command not found: step-10.txt
zsh: command not found: step-11.txt
zsh: command not found: step-12.txt
zsh: command not found: step-13.txt
zsh: command not found: step-14.txt
zsh: command not found: step-15.txt
zsh: command not found: step-16.txt
zsh: command not found: step-17.txt
zsh: command not found: step-18.txt
zsh: command not found: step-19.txt
zsh: command not found: step-1.txt
zsh: command not found: step-2.txt
zsh: command not found: step-3.txt
zsh: command not found: step-4.txt
zsh: command not found: step-5.txt
zsh: command not found: step-6.txt
zsh: command not found: step-7.txt
zsh: command not found: step-8.txt
zsh: command not found: step-9.txt
↵ Error. Exit status 127.
❯ for f in *.txt; do
mv $f $(echo $f | sed 's/txt/md/')
done
❯ ls
step-10.md step-12.md step-14.md step-16.md step-18.md step-1.md step-3.md step-5.md step-7.md step-9.md
step-11.md step-13.md step-15.md step-17.md step-19.md step-2.md step-4.md step-6.md step-8.md
Почему это работает, когда я помещаю $(echo $f | sed 's/txt/md/')
в строку с mv
, но не когда она назначена переменной? Почему в нем говорится command not found: $f
, когда мой цикл предоставляет $f
mv
команду в качестве аргумента?
Комментарии:
1. избавьтесь от обратной косой черты в конце строки
newname
назначения.
Ответ №1:
Эта обратная косая черта означает, что он оценивает
newname=$(echo $f | sed 's/txt/md/')mv $f $newname
который, конечно, рассматривает имя файла как имя выполняемой команды (mv является частью newname
переменной).
Вам sed
здесь вообще не нужно; просто используйте расширение параметров:
for f in *.txt; do
mv "$f" "${f/%txt/md}"
done
Существует также несколько различных программ с именами rename
( prename
rename.ul
, и т.д. в зависимости от операционной системы), Которые могут массово переименовывать файлы; проверьте справочные страницы, какие из них (если таковые имеются) вы установили и используете.
Комментарии:
1. В
zsh
${name/pattern/repl}
расширении a%
в начале шаблона означает, что он совпадает только в конце строки. А#
привязывается к началу.#%
означает, что шаблон должен соответствовать всей строке; или использовать${name:/pattern/repl}
для того же эффекта.2. в
${name...
том, что мы имеем дело с такой переменной, как$name
?? (синтаксис расширения оболочки часто сбивает меня с толку)3. и в
mv "$f" "${f/%txt/md}"
«f»${f/
есть f, потому что мы имеем дело с переменной с именем$f
?4. @alec Да.
zsh
в документации используется имя (а иногда и спецификация ) в разделе о расширении параметров. Это может быть простое имя переменной или строка, являющаяся результатом вложенного расширения, и т.д. В зависимости от того, что вы делаете. В данном случае переменнаяf
.5. Спасибо. Приятно узнать о функции поиска/замены расширения параметров.