LINUX.ORG.RU

Одна строчка bash

 


0

1

Есть строчка:

FILES=~/music\ films\ books/music/Borya\ Chistiy-/*/*.mp3

Далее идёт изменение расширения файлов и mv для замены:

mv $i $b

Но путь к файлу не виден как одно целое, выдаётся сообщение:

mv: не удалось выполнить stat для «/home/nirvana/music»: Нет такого файла или каталога
mv: не удалось выполнить stat для «films»: Нет такого файла или каталога

и т.д. Как бы без переименования директорий в версию без пробелов решить проблему?



Последнее исправление: NatNat (всего исправлений: 4)
roman@note:~$ FILES=~/music\ films\ books/music/Borya\ Chistiy-/*/*.mp3
roman@note:~$ echo $FILES
/home/roman/music films books/music/Borya Chistiy-/*/*.mp3

нутыпонял

roman@note:~$ FILES="~/music\ films\ books/music/Borya\ Chistiy-/*/*.mp3"
roman@note:~$ echo $FILES
~/music\ films\ books/music/Borya\ Chistiy-/*/*.mp3
roman@note:~$ 
roman77 ★★★★★
()
Ответ на: комментарий от roman77

Так уже пытался. )

mv: не удалось выполнить stat для «~/music\\»: Нет такого файла или каталога
mv: не удалось выполнить stat для «films\\»: Нет такого файла или каталога
mv: не удалось выполнить stat для «books/music/Borya\\»: Нет такого файла или каталога

NatNat
() автор топика

Правильный вариант. особенно если файлов очень много (тысячи)

find ~/music\ films\ books/music/Borya\ Chistiy-/ -name '*.mp3' |
 while read file; do
   newfile=$(basename "$file" .mp3).bmp;
   mv "$file" "$newfile"
 done

Другой вариант:

set ~/music\ films\ books/music/Borya\ Chistiy-/*/*.mp3
while [ $# -gt 0 ]; do
 newfile=$(basename "$1" .mp3).bmp;
 mv "$1" "$newfile"
 shift
done

третий вариант, с массивом (обрати внимание на кавычки, они обязательны):

FILES=(~/music\ films\ books/music/Borya\ Chistiy-/*/*.mp3)
for i in "${FILES[@]}"; do
 newfile=$(basename "$i" .mp3).bmp;
 mv "$i" "$newfile"
done

Четвёртый вариант, без массива, потому что он не нужен.

for i in ~/music\ films\ books/music/Borya\ Chistiy-/*/*.mp3; do
 newfile=$(basename "$i" .mp3).bmp;
 mv "$i" "$newfile"
done

legolegs ★★★★★
()
Последнее исправление: legolegs (всего исправлений: 4)
Ответ на: комментарий от anonymous
$ touch test\ test test\ asdf
$ a=test*
$ for i in $a; do rm $i; done
rm: невозможно удалить «test»: Нет такого файла или каталога
rm: невозможно удалить «asdf»: Нет такого файла или каталога
rm: невозможно удалить «test»: Нет такого файла или каталога
rm: невозможно удалить «test»: Нет такого файла или каталога
$ for i in "${a[@]}"; do rm $i; done
$
derlafff ★★★★★
()
Ответ на: комментарий от legolegs

Не знаю, что я мог вставить не так, но все файлы просто... удалились! Хорошо, это копии были. =)

Если вместо mv поставить cp, то всё останется в первозданном виде.

Четвёртый вариант, без массива, потому что он не нужен.

for i in ~/music\ films\ books/music/Borya\ Chistiy-/*/*.mp3; do
 newfile=$(basename "$i" .mp3).bmp;
 mv "$i" "$newfile"
done
NatNat
() автор топика

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

comp00 ★★★★
()
Ответ на: комментарий от comp00

Это точно. Но при вводе пути к файлу неудобно туда-сюда раскладку менять. )

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

NatNat
() автор топика
Ответ на: комментарий от NatNat

Не знаю, что я мог вставить не так, но все файлы просто... удалились!

Поэтому первоначальный вариант должен содержать что-то типа

...
echo "mv \"$i\" \"$newfile\""
...
В играх тоже не сохранялся перед тем как босса бить?

Kroz ★★★★★
()
Ответ на: комментарий от NatNat

mv не удаляет файлы, он их может только перезаписывать, поэтому, в подобных скриптах, где одни фалы не должны записываться под именем уже существующих, лучше указывать ″mv″ опцию ″-i″ или ″-n″.

mky ★★★★★
()

открой для себя двойные кавычки.

"такие"

emulek
()
Ответ на: комментарий от legolegs

Правильный вариант

мал ты ещё для правильных вариантов.

Не претендуя на правильность дам свой вариант:

find dir/ -name '*.mp3' -exec mv -t target/ +

emulek
()
Ответ на: комментарий от derlafff

for i in $a; do rm $i; done

а ты поняшка, не умеешь двойные кавычки, вот они у тебя и не работают.

emulek
()
Ответ на: комментарий от mky

mv не удаляет файлы, он их может только перезаписывать

бред и 4.2

mv наоборот не может перезаписывать и удаляет. Потому можно и нужно юзать --backup (с ним mv не удаляет старый файл, а только меняет имя).

ЗЫЖ зачем людей путаешь?

emulek
()
Ответ на: комментарий от emulek

Это не ко мне, это к разработчикам ″mv″, у них в докуменации фигурирует термин ″overwrite″.

А использовать опцию ″--backup″ в скриптах, подобных написанному ТС'ом, хуже, чем ″-i″. В случае типовой ошибки, когда все файлы перемещаются под одно имя, ″--interactive″ выдаст предупреждение уже на втором файле и можно ″Ctrl+C″ и искать ошибку.

mky ★★★★★
()
Ответ на: комментарий от legolegs

твой правильный вариант сломается, если в названии файла появится '\n'

maloi ★★★★★
()
Ответ на: комментарий от mky

Это не ко мне, это к разработчикам ″mv″, у них в докуменации фигурирует термин ″overwrite″.

цитату можно?

А использовать опцию ″--backup″ в скриптах, подобных написанному ТС'ом, хуже, чем ″-i″. В случае типовой ошибки, когда все файлы перемещаются под одно имя

я разве говорил, что надо обязательно --backup без параметра?

emulek
()
Ответ на: комментарий от emulek

man страница у разных версий coreutils разная, но вот вывод самой команды mv, вроде, давно неизменный:

$ mv --help
...
  -f, --force                  do not prompt before overwriting
  -i, --interactive            prompt before overwrite
  -n, --no-clobber             do not overwrite an existing file

Я отвечал на фразу «файлы просто... удалились!» и своим ответом хотел сообщить ТС'у, что ″mv″, в отличии от ″rm″, просто так не удаляет файлы, он может под именем существующего файла записать другой файл и это поведение настраивается. Не знаю, может ″overwritе″ нужно переводить другим словом, но меня и «перезаписывает» устраивает.

mky ★★★★★
()
Ответ на: комментарий от mky

-i, --interactive prompt before overwrite

ну там только эффект как при перезаписи. На самом деле файл не перезаписывается, а создаётся новый. А вот подтверждение даётся именно в том случае, если эффект операции равносилен перезаписи файлов.

Да только толку от этой опции никакого, если оно для многих файлов. Проще взять mc или ФМ какой-нить. Консоль она для интерактива не предназначена.

Я всё к тому говорил, что в CLI проще постфактум обрабатывать особые случаи. Или предварительно. Но никак не интерактивно.

А в скрипте, который тут ТС писал надо rename юзать, а не mv.

$ find . -type f -name "*.bmp" -exec rename --verbose .bmp .mp3 {} +
`./a b c/d e f .bmp' -> `./a b c/d e f .mp3'
`./10.bmp' -> `./10.mp3'
`./9.bmp' -> `./9.mp3'
`./8.bmp' -> `./8.mp3'
`./7.bmp' -> `./7.mp3'
`./6.bmp' -> `./6.mp3'
`./5.bmp' -> `./5.mp3'
`./4.bmp' -> `./4.mp3'
`./3.bmp' -> `./3.mp3'
`./2.bmp' -> `./2.mp3'
`./1.bmp' -> `./1.mp3'
emulek
()
Ответ на: комментарий от Kroz

Ты фразу не целиком вставил. =)

Не знаю, что я мог вставить не так, но все файлы просто... удалились! Хорошо, это копии были. =)

NatNat
() автор топика
Ответ на: комментарий от legolegs

Да, я понял, все обвинения снимаются. )

Они мереместились в текущий каталог, откуда запускалдся скрипт сорри, я забыл что basename ест пути

P.S. Прости, долго не отвечал, в общаге инет отрубили.

NatNat
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.