URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9142
[ Назад ]

Исходное сообщение
"Как выделить три последних символа имени файла?"

Отправлено Dart_Vitalus , 22-Май-11 20:50 
Дано: в каталоге лежат несколько файлов с произвольными именами (с возможным содержанием пробелов).
Задача №1: в цикле добавить к именам файлов в конец слово "new", чтобы получились файлы типа "имя_файлаnew.расширение".
Задача №2: в цикле сделать обратное действие, т.е. у файлов с "new" на конце имени убрать это "new" на конце имени.

Мои потуги:

Задача №1:
for i in ...
do
    mv '$i' '$i.new'
done

задачу №2 вообще не знаю как решить :(

помогите, буду очень благодарен!


Содержание

Сообщения в этом обсуждении
"Как выделить три последних символа имени файла?"
Отправлено phpcoder , 22-Май-11 21:00 
>[оверквотинг удален]
> Задача №1: в цикле добавить к именам файлов в конец слово "new",
> чтобы получились файлы типа "имя_файлаnew.расширение".
> Задача №2: в цикле сделать обратное действие, т.е. у файлов с "new"
> на конце имени убрать это "new" на конце имени.
> Мои потуги:
> Задача №1:
> for i in ...
> do
>     mv '$i' '$i.new'
> done

И оно у вас работает? С одинарными кавычками?

> задачу №2 вообще не знаю как решить :(

Например, так:

for i in *; do
    mv -vf -- "$i" "$(echo "$i" | sed 's|\.new$||')"
done


"Как выделить три последних символа имени файла?"
Отправлено Dart_Vitalus , 23-Май-11 00:25 
> И оно у вас работает? С одинарными кавычками?

в том-то и дело что не работает)


"Как выделить три последних символа имени файла?"
Отправлено Name , 22-Май-11 23:46 
>[оверквотинг удален]
> Задача №2: в цикле сделать обратное действие, т.е. у файлов с "new"
> на конце имени убрать это "new" на конце имени.
> Мои потуги:
> Задача №1:
> for i in ...
> do
>     mv '$i' '$i.new'
> done
> задачу №2 вообще не знаю как решить :(
> помогите, буду очень благодарен!

for file in /dir/*; do mv ${file} ${file}.new; done
for file in /dir/*; do mv ${file} ${file%...}; done

Пример.
mkdir ~/dir
touch ~/dir/some\ file
for file in ~/dir/*; do mv ${file} ${file}.new; done
for file in ~/dir/*; do mv ${file} ${file%.???}; done


"Как выделить три последних символа имени файла?"
Отправлено sany , 23-Май-11 00:34 
>[оверквотинг удален]
>> done
>> задачу №2 вообще не знаю как решить :(
>> помогите, буду очень благодарен!
> for file in /dir/*; do mv ${file} ${file}.new; done
> for file in /dir/*; do mv ${file} ${file%...}; done
> Пример.
> mkdir ~/dir
> touch ~/dir/some\ file
> for file in ~/dir/*; do mv ${file} ${file}.new; done
> for file in ~/dir/*; do mv ${file} ${file%.???}; done

1) на сколько я понял, сложность была в том, чтобы вставить суффикс между именем файла и расширением файла, а не просто дописать в конец, то есть чтобы расширение файла не поменялось
2) использование ${file} приведёт к ошибке для файлов, содержащих пробел, нужно "${file}"


"Как выделить три последних символа имени файла?"
Отправлено Name , 23-Май-11 17:59 
>[оверквотинг удален]
>> for file in /dir/*; do mv ${file} ${file%...}; done
>> Пример.
>> mkdir ~/dir
>> touch ~/dir/some\ file
>> for file in ~/dir/*; do mv ${file} ${file}.new; done
>> for file in ~/dir/*; do mv ${file} ${file%.???}; done
> 1) на сколько я понял, сложность была в том, чтобы вставить суффикс
> между именем файла и расширением файла, а не просто дописать в
> конец, то есть чтобы расширение файла не поменялось
> 2) использование ${file} приведёт к ошибке для файлов, содержащих пробел, нужно "${file}"

Пример.
mkdir ~/dir
touch ~/dir/some\ file
touch ~/dir/some\ file.extension
cd ~/dir
export addword=".new"
for file in *; do
case ${file##*.} in
${file}) echo "file not have extension";;
*)  mv -v ${file} ${file%.*}${addword}.${file##*.};;
esac;
done

for file in *; do
case ${file##*.} in
${file}) echo "file not have extension";;
*)  mv -v ${file} ${file%${addword}.*}.${file##*.};;
esac;
done

Спасибо за замечание, невнимателен. Сложностей здесь нет, достаточно использовать "Parameter Expansion".
>использование ${file} приведёт к ошибке для файлов, содержащих пробел, нужно "${file}"

Прошу внимательней посмотреть на пример, some\ file содержит пробел. В использвуемой конструкции экранирование не требуется.
Пример.
file=file\ name\ with\ blank
touch ${file}
mv -v ${file} ${file}.new
«file name with blank» -> «file name with blank.new»

Примечание.
В скрипте, можно предусмотреть как необходимо обрабатывать файлы без расширений (показано в примере).
И как следует поступать с определёнными расширениями, например, file.tar.gz


"Как выделить три последних символа имени файла?"
Отправлено sany , 23-Май-11 18:26 
> Прошу внимательней посмотреть на пример, some\ file содержит пробел. В использвуемой конструкции
> экранирование не требуется.
> Пример.
> file=file\ name\ with\ blank
> touch ${file}
> mv -v ${file} ${file}.new
> «file name with blank» -> «file name with blank.new»

без кавычек ошибку выдаёт:
$ file=file\ name\ with\ blank
$ touch ${file}
$ mv -v ${file} ${file}.new
mv: target `blank.new' is not a directory

то есть файл с пробелом воспринимается за 4 файла.
я не знаю, что у вас за шелл, но мои (bash,dash) требуют кавычек вокруг ${file}


"Как выделить три последних символа имени файла?"
Отправлено Name , 23-Май-11 21:43 
>[оверквотинг удален]
>> mv -v ${file} ${file}.new
>> «file name with blank» -> «file name with blank.new»
> без кавычек ошибку выдаёт:
> $ file=file\ name\ with\ blank
> $ touch ${file}
> $ mv -v ${file} ${file}.new
> mv: target `blank.new' is not a directory
> то есть файл с пробелом воспринимается за 4 файла.
> я не знаю, что у вас за шелл, но мои (bash,dash) требуют
> кавычек вокруг ${file}

Извините, особенность shell'а. POSIX требует экранирование.


"Как выделить три последних символа имени файла?"
Отправлено sany , 23-Май-11 00:18 
Решение первой задачи:
for ii in *;do mv "$ii" "${ii%.*}.new.${ii##*.}";done

"Как выделить три последних символа имени файла?"
Отправлено sany , 23-Май-11 00:31 
> Решение первой задачи:
> for ii in *;do mv "$ii" "${ii%.*}.new.${ii##*.}";done

решение  обратной задачи:
for ii in *;do name=$(echo "${ii%.*}" | sed "s|\.new$||") && mv "$ii" "$name.${ii##*.}";done


"Как выделить три последних символа имени файла?"
Отправлено Andrey Mitrofanov , 23-Май-11 07:41 
>>${ii%.*}.new.${ii##*.}"
> name=$(echo "${ii%.*}" | sed "s|\.new$||")

А чего второе без sed-а не сделал?


"Как выделить три последних символа имени файла?"
Отправлено sany , 23-Май-11 15:33 
>>>${ii%.*}.new.${ii##*.}"
>> name=$(echo "${ii%.*}" | sed "s|\.new$||")
> А чего второе без sed-а не сделал?

хорошее замечание, вот
for ii in *;do mv -- "$ii" "${ii%.new.*}.${ii##*.}";done


"Как выделить три последних символа имени файла?"
Отправлено Dart_Vitalus , 24-Май-11 00:43 
> Решение первой задачи:
> for ii in *;do mv "$ii" "${ii%.*}.new.${ii##*.}";done
> решение  обратной задачи:
> for ii in *;do mv -- "$ii" "${ii%.new.*}.${ii##*.}";done

Прошу прощения, а можно вас попросить краткий комментарий дать, например зачем двойной тире во второй операции а также двойной # в обеих если вас не затруднит :)



"Как выделить три последних символа имени файла?"
Отправлено Name , 24-Май-11 09:53 
>> Решение первой задачи:
>> for ii in *;do mv "$ii" "${ii%.*}.new.${ii##*.}";done
>> решение  обратной задачи:
>> for ii in *;do mv -- "$ii" "${ii%.new.*}.${ii##*.}";done
> to sany
> Прошу прощения, а можно вас попросить краткий комментарий дать, например зачем двойной
> тире во второй операции а также двойной # в обеих если
> вас не затруднит :)

mv --
программа mv написанна с использование функции getopt, для разбора аргументов, что позволяет указать завершение параметров программы, т.е все последйющие аргументы будут восприниматься как не-параметры.
Пример.
toch -- file -f
mv -f -- file file.new # -f является параметром программы mv
mv -- -f -f.new # -f является файлом

${ii##*.} ${ii%.*}
Это "Parameter Expansion" или "Parameter substitution", "Раскрытие/подстановка параметров".
${параметр(%,%%,#,##)шаблон_из_регулярных_выражений}
${параметр#шаблон} - подставляет значение параметра, в котором из головной части удалён наименьший фрагмент, удовлетворяющий шаблону.
${параметр##шаблон} - подставляет значение параметра, в котором из головной части удалён наибольший фрагмент, удовлетворяющий шаблону.
${параметр%шаблон} - подставляет значение параметра, в котором из хвостовой части удалён наименьший фрагмент, удовлетворяющий шаблону.
${параметр%%шаблон} - подставляет значение параметра, в котором из хвостовой части удалён наибольший фрагмент, удовлетворяющий шаблону.
Пример
export ii=new.file.new

echo ${ii#*.}
file.new

echo ${ii##*.}
new

echo ${ii%.*}
new.file

echo ${ii%.*}
new

http://ru.wikipedia.org/wiki/Регулярные_выражения

P.s.
>у вас за шелл
>можно вас попросить

/вас/Вас/


"Как выделить три последних символа имени файла?"
Отправлено sany , 24-Май-11 15:52 
>>> Решение первой задачи:
>>> for ii in *;do mv "$ii" "${ii%.*}.new.${ii##*.}";done
>>> решение  обратной задачи:
>>> for ii in *;do mv -- "$ii" "${ii%.new.*}.${ii##*.}";done
>> to sany
>> Прошу прощения, а можно вас попросить краткий комментарий дать, например зачем двойной
>> тире во второй операции а также двойной # в обеих если
>> вас не затруднит :)
> ${параметр(%,%%,#,##)шаблон_из_регулярных_выражений}

это не регулярные выражения, это Shell Patterns
подробнее "Подстановка имен файлов" http://www.opennet.me/man.shtml?topic=bash&category=1#lbBD


"Как выделить три последних символа имени файла?"
Отправлено Name , 24-Май-11 20:09 
>[оверквотинг удален]
>>>> for ii in *;do mv "$ii" "${ii%.*}.new.${ii##*.}";done
>>>> решение  обратной задачи:
>>>> for ii in *;do mv -- "$ii" "${ii%.new.*}.${ii##*.}";done
>>> to sany
>>> Прошу прощения, а можно вас попросить краткий комментарий дать, например зачем двойной
>>> тире во второй операции а также двойной # в обеих если
>>> вас не затруднит :)
>> ${параметр(%,%%,#,##)шаблон_из_регулярных_выражений}
> это не регулярные выражения, это Shell Patterns
> подробнее "Подстановка имен файлов" http://www.opennet.me/man.shtml?topic=bash&category=1#lbBD

Спасибо за замечание. Я не знаяю "Shell Patterns",
${параметр(%,%%,#,##)шаблон_из_регулярных_выражений}
${параметр(%,%%,#,##)шаблон_из_регулярных_выражений_shell}
${параметр(%,%%,#,##)pattern_matching}


"Как выделить три последних символа имени файла?"
Отправлено Dart_Vitalus , 23-Май-11 00:25 
спасибо большое, друзья!! завтра попробую - отпишусь о результате!!! 3 разных варианта предложено - како-то точно подойдёт :)
ещё раз благодарю!!!



"Как выделить три последних символа имени файла?"
Отправлено pavlinux , 23-Май-11 16:21 
>[оверквотинг удален]
> Задача №2: в цикле сделать обратное действие, т.е. у файлов с "new"
> на конце имени убрать это "new" на конце имени.
> Мои потуги:
> Задача №1:
> for i in ...
> do
>     mv '$i' '$i.new'
> done
> задачу №2 вообще не знаю как решить :(
> помогите, буду очень благодарен!

1.


# rename .jpg .new.jpg *.jpg

2.

# rename .new.jpg .jpg *.jpg

The rename command is part  of  the  util-linux  package  
and  is  available  from ftp://ftp.kernel.org/pub/linux/utils/util-linux