От сега предупреждавам – тази статия покрива много основни неща. Пиша я най-вече за себе си, за да не забравя как се прави, но ако успея да помогна на някого – добре сте дошли.
Както винаги – пиша за разрешаването на един единствен проблем. Не претендирам това да е най-лесни, най-елегантния или най-красивия начин. Сигурно има десет или 20 други начина с които да разрешите този проблем. Аз лично избрах този, защото мога да го имплементирам лесно.
Тъй като забравям изключително много, на повечето си телефони имам програмка за запис на разговори. Това е чудесно, но вече бях натрупал едно количество от около 250 файла със запис преди да разбера каква конвенция за името използва програмата, която използвах – [Име на контакта]_[Номер]_[Час]-[Минута]-[Секунда]_[Дата]-[Месец]-[Година].wav … нали се сещате каква бъркотия създава това, като се опитваш да търсиш разговор по дата … още по-лошо – когато знаеш ориентировъчен период … абе тъпотии. Тогава реших проблем частично, като свалих всички разговори които имах в една папка и промених конвенцията на [Номер]_[Час]-[Минута]-[Секунда]_[Дата]-[Месец]-[Година].wav … защо, ще попитате? Защото недогледах номерацията. Докато онзи ден не видях точно къде ми е грешката. Имам 1300 файла в две директории, които са непретърсваеми поради глупостта ми …
Реших, че няма да е лошо да седна и да напиша малко скриптче което да преименува файловете, така, че да станат удобни за ровене, а именно [Номер]_[Час]-[Минута]-[Секунда]_[Дата]-[Месец]-[Година].wav да стане в YYYYMMDD-HHMMSS_нещо си. Речено сторено …
Тук ще ви предупредя, че смятам да разгледам всяка стъпка от създаването на скрипта … ако знаете как се прави – спрете да четете. Не ви трябва това. Ако все пак ви се иска – давайте на татък.
Тъй като имаме да извършим неопределен брой операции, няма да е никак лошо да ги зациклим малко … за тези които не знаят (аз винаги го забравям) в Bash циклите са с for.
#/bin/bash for file in voix/*/*.wav dodone
Хубавото е че bash си взима съдържанието на директорията рекурсивно и го пуска като параметър на for. Или, преведено на човешки – докато имаш file в директорията прави следното.
Тъй като $file връща цялото име на файла с който ще работим, а именно – voix/incoming(или outgoing)/нещоси, а аз искам и после да си ги разделя по папки, значи трябва да взема директорията за да я използвам.
#/bin/bashfor file in voix/*/*.wav dostate=`echo $file | cut -d/ -f2`nfile=`echo $file | cut -d/ -f3`done
На $state оказваме под директорията в която се намира файла с който работим (или раздели string-а на името на файла по всяка / и вземи втория възможен отговор. Това ни дава състоянието (дали е входящо или изходящо обаждане). После вземи третия параметър, защото това ти е името на самият файл, от което трябва да вземем информация за разговора, за да престрактурираме името – $nfile.
Основно името на файла, може да се разглежда като 4 основни части – [номер]_[време]_[дата].окончание, за това и ги присъединявам на 4 отделни променливи (ще видите, че по принцип се делят от _, но окончанието е разделено от останалото с . – тук на помощ идва последователното свързване на команди … но нека ви го покажа и да обясня после:
phn=`echo $nfile | cut -d_ -f1` rtime=`echo $nfile | cut -d_ -f2` rdate=`echo $nfile | cut -d_ -f3 | cut -d. -f1` rext=`echo $nfile | cut -d_ -f3 | cut -d. -f2`
Както и с $state по-горе, $phn (номер) и $rtime (време) се взимат като се раздели стринга на $nfile и взимаме съответно първата и втората част. $rdate и $rext обаче са различна картинка. Тъй като и за двете имаме нужда от част от третата част, за това и използваме отново cut, но този път с . и то само към третата част от низа …
Разбира се, след като имаме отделните части е време да ги разбием отново (датата и времето трябва да се подредят както трябва):
year=`echo $rdate | cut -d- -f3` month=`echo $rdate | cut -d- -f2` day=`echo $rdate | cut -d- -f1`hour=`echo $rtime | cut -d- -f1` minute=`echo $rtime | cut -d- -f2` second=`echo $rtime | cut -d- -f3`
Дори няма да обяснявам тук – вече съм обяснил всички части по-горе.
Тъй като искам да мога спокойно да местя директорията с преименуваните файлове, без да се притеснявам от загуби, а и не мога да променя voix, защото тази папка се синхронизира с телефона, нека проверим дали voix.ren (директория за преименуваните файлове) съществува, ако не – нека я създадем:
if [ ! -d "voix.ren" ]; then mkdir voix.ren fi
Добре де, но нали имаме и входящи и изходящи разговори? Значи е добре да създадем и тяхната структура (нали помните $state?):
if [ ! -d voix.ren/$state ]; then mkdir voix.ren/$state fi
А така … сега вече сме готови …
След като сме взели всички необходими променливи и сме подготвили структурата, време е да подредим новото име и да преименуваме файловте. Аз лично предпочитам да придам новото име на променлива и после нея на mv, но това си е избор на всеки.
newname="voix.ren/"$state"/"$year$month$day"-"$hour$minute$second"_"$phn"."$rextecho $file" -> "$newname mv $file $newname
#/bin/bashfor file in voix/*/*.wav dostate=`echo $file | cut -d/ -f2`nfile=`echo $file | cut -d/ -f3`phn=`echo $nfile | cut -d_ -f1` rtime=`echo $nfile | cut -d_ -f2` rdate=`echo $nfile | cut -d_ -f3 | cut -d. -f1` rext=`echo $nfile | cut -d_ -f3 | cut -d. -f2`year=`echo $rdate | cut -d- -f3` month=`echo $rdate | cut -d- -f2` day=`echo $rdate | cut -d- -f1`hour=`echo $rtime | cut -d- -f1` minute=`echo $rtime | cut -d- -f2` second=`echo $rtime | cut -d- -f3`if [ ! -d "voix.ren" ]; then mkdir voix.ren fiif [ ! -d voix.ren/$state ]; then mkdir voix.ren/$state finewname="voix.ren/"$state"/"$year$month$day"-"$hour$minute$second"_"$phn"."$rextecho $file" -> "$newname mv $file $newname done
Вие разбира се може да не го направите така. Както казах – не е красиво. Но е функционално, а на мен ми трябва точно за това – да направи това, което искам от кода. Не искам да прави фокуси или да ми прави кафе. Искам да хване и да преименува едни файлове.
Надявам се съм ви бил полезен.
Ваш,
Lucifer
Вашият коментар