LINUX.ORG.RU

Как не надо писать скрипты

 


0

1

Название темы для самокритики, а дело вот в чем:
- понадобилось переименовать расширения всех мультимедийных файлов на диске с больших букв на маленькие.

Ну не нравится мне такой вид: Антонов.MP3
гораздо лучше смотрится так: Антонов.mp3

Итак задача: найти в текущем каталоге все мультимедийные файлы и переименовать их расширения из ЗАГЛАВНЫХ в прописные символы.

Начал вспоминать, какая команда в беше переименовывает файлы.
И был жутко удивлен открытием - оказывается, в могучий BASH такую команду до сих пор не завезли! :-O
Даже в убогом ДОСе она есть, а тут нет, выкручиваются костылем на основе mv.

Костылем заморачиваться не стал, а нашел приложение, которое занимается переименованием, и которое так и называется - rename
На его основе быстренько накидал «переименователь» (слабонервным просьба отвернуться :-) -

find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(BMP)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(JPG)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(JPEG)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(GIF)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(PNG)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(AVI)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(MKV)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(MOV)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(MPG)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(MKV)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(SWF)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(WEBM)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(DIVX)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(MPEG)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(MKA)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(FLV)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(FLAC)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(OGG)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(OGM)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(QT)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(TS)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(ASF)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(WMA)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(WMV)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(WAV)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(PCM)$|$1\L$2|' {} \;
find . -depth -print0 | xargs -0 -n 1 rename -v 's|(.*\.)(AAC)$|$1\L$2|' {} \;

Запустил творение и начал ждать. Однако ожидание затянулось, и оставил процесс на ночь.

Каково же было мое удивление, когда выяснилось, что за 7 часов процесс не только не завершился, а переименовал всего ... 227 найденных BMP-файлов! Т.е. до других расширений даже не добрался.

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

Тогда переделал скрипт для ускорения, точно не помню, но кажется так, дело давно было -

 /usr/bin/perl -w /usr/bin/rename -v s#(.*\.)(PNG)$#$1\L$2#
но это мало что дало, поскольку Пёрл не исправить, поэтому забросил это дело.

А как бы поступили вы, если переименовать в Bash?

★★★★★

Даже в убогом ДОСе она есть,

Что? В ДОС никогда не было разницы между регистром букв в названиях файлов.

Утилит для массового переименования существует огромное количество, включая интерактивные GUI. Но я их никогда не запоминаю, как и способ использования, приходится каждый раз заново яндексить.

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

не совсем. :)
dpkg -S ищет в уже установленных пакетах. точнее в листингах /var/lib/dpkg/info/%package_name%.list
apt-file скачивает с серверов листинги файлов всего репозитория и ищет в них. листинги кстати надо еще и обновлять перед поиском.

pfg ★★★★★
()
Последнее исправление: pfg (всего исправлений: 1)
Ответ на: комментарий от pfg

Я к тому что apt-file отсутствует в дистрах (во всяком случае в linuxmint). Не знаю, может раньше был из коробки.

А так то «я не настоящий сварщик», что касается юбунтоподобных ) и мог ошибиться по поводу dpkg -S. Но получается, эти дистры не имеют дефолтных инструментов, подобных арчевскому pacman -F? Только доустанавливать?

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

это стандартный компонент системы apt.
минтяра вполне может просто его не поддерживает, зависит от мейнтейнеров минта.

dpkg -S ищет по локально создаваемыми при установке пакета листингам.
для того чтобы искать по всему репозиторию, нужны естественно листинги репозитория, чтобы получить их локально их надо скачать с сервера. опять же репозиторий может не фомировать такие листинги…

с пакманом не знаком, предположу что в нем «тоже самое, только в профиль».

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

минтяра вполне может просто его не поддерживает, зависит от мейнтейнеров минта.

Посмотрел в ubuntu-22.10-desktop-amd64.iso, тоже нет apt-file. Возможно, «мейнтейнеры всех стран, объединились». :)

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

Ну такое себе, установочный образ на 4 Gb, где не все пакеты ПМ (пакетный менеджер). ) Я не хочу лезть в чужую кухню со своими ‘грязными’ сапогами, но вот в арче… :)

Может непонятно сразу пояснил, но я эти дистры запускаю на посмотреть/‘пощупать’ в LiveCD в вирте, поэтому хотелось бы дефолт уж в таких то вещах. И я думал, что просто чего-то не знаю и есть встроенный функционал.

krasnh ★★★
()
Ответ на: комментарий от no-dashi-v2

задачу, которую 25 лет назад задавали студентам в качестве лабораторной работы на 30 минут после двухнедельного знакомства с командной строкой.

Не подскажет ли гуру сборник подобных задач? Требуется что-то более общее/осмысленное, чем сборник Абрамяна (1000 раз напишите фигню для освоения синтаксиса ЯП), но более простое чем «написать браузер/ОСь». Заранее спасибо.

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

Позаимствовать с LeetCode/CodeWars и массы подобных сервисов? Правда, это может быть нарушением их пользовательского соглашения. С другой стороны, можно сразу туда направлять людей.

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

ибо в дебиане cfdisk лежит в указанных на репозитории пакетах и более нигде.

Да, лежит - где попало. Было бы иначе, он бы установился этой - командой:

apt install cfdisk
но она его - не видит. Synaptic его тоже не видит.
apt-file search
- зачем мне устанавливать еще какой-то специальный поиск?
Если бы cfdisk нормаль но прописан в репах. то он бы установился штатной установкой.

Поэтому проще дефолтный dpkg -S file.

При чем тут это? Речь не о поиске в системе, а об установке из репозитария.

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

все правильно он лежит в пакете fdisk в который упаковано три утилиты по работе с диском.

fdisk — классическая утилита с текстовым интерфейсом. cfdisk имеет более удобный псевдографический интерфейс, основанный на библиотеке curses. sfdisk предназначен в основном для автоматизации действий и использования в командных сценариях.

засовывать каждый отдельный бинарь в каждый отдельный пакет… ну такоэ… ты просто путаешь свое мнение с реальностью
он вполне нормально прописан в репах. то, что ты чегото не умеешь в линуксе, еще ничего не говорит о линуксе :)

ты мне вот чего скажи где и в чем ты вот такое нашел.

Но cfdisk фига не нашелся.
А знаете где он нашелся, и то чисто случайно, методом научного тыка?
В пакете util-linux-locales !

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

куча пакетов гигантского репозитория дебиана отсуствует в усатновочном образе :)
и я думаю это нормально.
тебе никогда не то, что не понадобятся, ты наврядли слышал о применении пакетов binkd или hamradio-all :-)

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

А ты поиском не пробовал пользоваться?

└─> apt-cache search cfdisk
fdisk - управления разделами жёсткого диска
libfdisk1 - библиотека fdisk для разбиения диска на разделы
gpart - Guess PC disk partition table, find lost partitions
mtd-utils - Memory Technology Device Utilities
libfdisk-dev - fdisk partitioning library - headers
└─> dpkg -S cfdisk
fdisk: /sbin/cfdisk
fdisk: /usr/share/bash-completion/completions/cfdisk
fdisk: /usr/share/man/man8/cfdisk.8.gz

shell-script ★★★★★
()
Ответ на: комментарий от pfg

засовывать каждый отдельный бинарь в каждый отдельный пакет…

В отдельный - где вы такое услышали? Это ваши фантазии.
Речь совсем о другом - о том, что cfdisk засунули хрен знает куда - в util-linux-locales.
При чем тут cfdisk к локализации?
Если бы он был в util-linux, то вопросов бы не было.

И теме не менее, зачем мне нужно заниматься какими-то отдельными поисками? Команда установки

apt  install  cfdisk
обязана сама его найти и установить, как она делает со всеми другими утилитами.

Когда устанавливаю Firefox, zram-tools и прочее, их почему-то не приходится их искать - установщик их сам находит и устанавливает.
А для установки cfdisk почему-то требуются отдельные пляски с бубном - поиск и прочее :-)

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

еще раз
в репозитории дебиана в пакете util-linux-locales я не нашел ни одного упоминания cfdisk.
в каком месте и как ты нашел что внутри пакета util-linux-locales находится cfdisk ??

система тебе ничем не обязана :)

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

Сейчас и я не нашел его в этом пакете. Посмотрел свои записки, и оказалось, что данная ситуация с cfdisk, когда я его искал, была 2022-08-05.
Вероятно, где-то что-то исправили.

Но и сегодня команда его установки изображает фигу -

apt install cfdisk
Чтение списков пакетов… Готово
Построение дерева зависимостей… Готово
Чтение информации о состоянии… Готово         
E: Невозможно найти пакет cfdisk
cfdisk, ау, где ты? Впрочем, фиг с ним, я его еще тогда поставил, из того самого «locales». так что пока не надо.

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

Зачем быстрее? Меня полторы секунды вполне устраивают :-)
Тем более это не на сторонних утилитах, которые сегодня есть, а завтра может и не быть (как MEdit), а на беше, который всегда под рукой.

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

асболютно точное соответствие желанию кнопки «сделать все хорошо» :)
вот такая вот система, незапиленная под тупого и прямого как топор, пользователя…
для рядового пользователя и gparted сложон.
tui не для тебя - в нем дофига маны надо читать и думать надо прочитанным и, как следствие, четко знать как правильно нетривиальные с первого взгляда строки писать.

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

tui не для тебя - в нем дофига маны надо читать и думать надо прочитанным

Ошибаешься - только что чуть выше я написал, что предпочел TUI вместо GUI.
И так поступаю часто, если позволяет ситуация.
Потому что TUI работает всегда, в отличие от GUI, у которых то дистрибутив не тот, то зависимостей не хватает, то ли еще какие-то артефакты.

chukcha ★★★★★
() автор топика

Если часто используете самописные, хоть чуть-чуть сложные скрипты, используйте для этого любой, удобный Вам, нормальный ЯП. Писать что-то, хоть немного сложное, на bash-е - это боль… Не зря многие админы изучают тот же Python.

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

Какая принципиальная разница между mv file1 file 2 и rename file1 file2?

Во первых, это не семантичненько.

Во вторых, вместо

mv /foo1/foo2/foo3/foo4/foo5/foo6/bar1 /foo1/foo2/foo3/foo4/foo5/foo6/bar2 

гораздо нагляднее написать

rename /foo1/foo2/foo3/foo4/foo5/foo6/bar1 bar2 
Psilocybe ★★★★
()