от Lucifer

bashОт сега предупреждавам – тази статия покрива много основни неща. Пиша я най-вече за себе си, за да не забравя как се прави, но ако успея да помогна на някого – добре сте дошли.

Както винаги – пиша за разрешаването на един единствен проблем. Не претендирам това да е най-лесни, най-елегантния или най-красивия начин. Сигурно има десет или 20 други начина с които да разрешите този проблем. Аз лично избрах този, защото мога да го имплементирам лесно.

Проблема:

Тъй като забравям изключително много, на повечето си телефони имам програмка за запис на разговори. Това е чудесно, но вече бях натрупал едно количество от около 250 файла със запис преди да разбера каква конвенция за името използва програмата, която използвах – [Име на контакта]_[Номер]_[Час]-[Минута]-[Секунда]_[Дата]-[Месец]-[Година].wav … нали се сещате каква бъркотия създава това, като се опитваш да търсиш разговор по дата … още по-лошо – когато знаеш ориентировъчен период … абе тъпотии. Тогава реших проблем частично, като свалих всички разговори които имах в една папка и промених конвенцията на  [Номер]_[Час]-[Минута]-[Секунда]_[Дата]-[Месец]-[Година].wav … защо, ще попитате? Защото недогледах номерацията. Докато онзи ден не видях точно къде ми е грешката. Имам 1300 файла в две директории, които са непретърсваеми поради глупостта ми …

Решение:

Реших, че няма да е лошо да седна и да напиша малко скриптче което да преименува файловете, така, че да станат удобни за ровене, а именно [Номер]_[Час]-[Минута]-[Секунда]_[Дата]-[Месец]-[Година].wav да стане в YYYYMMDD-HHMMSS_нещо си. Речено сторено …

Тук ще ви предупредя, че смятам да разгледам всяка стъпка от създаването на скрипта … ако знаете как се прави – спрете да четете. Не ви трябва това. Ако все пак ви се иска – давайте на татък.

Стъпка 1 – Цъкълът!

Тъй като имаме да извършим неопределен брой операции, няма да е никак лошо да ги зациклим малко … за тези които не знаят (аз винаги го забравям) в Bash циклите са с for.

#/bin/bash

for file in voix/*/*.wav
do
done

Хубавото е че bash си взима съдържанието на директорията рекурсивно и го пуска като параметър на for. Или, преведено на човешки – докато имаш file в директорията прави следното.

Стъпка 2 – Директории и имена.

Тъй като $file връща цялото име на файла с който ще работим, а именно – voix/incoming(или outgoing)/нещоси, а аз искам и после да си ги разделя по папки, значи трябва да взема директорията за да я използвам.

#/bin/bash
for file in voix/*/*.wav
do
    state=`echo $file | cut -d/ -f2`
    nfile=`echo $file | cut -d/ -f3`

done

На $state оказваме под директорията в която се намира файла с който работим (или раздели string-а на името на файла по всяка / и вземи втория възможен отговор. Това ни дава състоянието (дали е входящо или изходящо обаждане). После вземи третия параметър, защото това ти е името на самият файл, от което трябва да вземем информация за разговора, за да престрактурираме името – $nfile.

Стъпка 3 – част от името.

Основно името на файла, може да се разглежда като 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`

Дори няма да обяснявам тук – вече съм обяснил всички части по-горе.

Стъпка 4 – Съществувам ли?

Тъй като искам да мога спокойно да местя директорията с преименуваните файлове, без да се притеснявам от загуби, а и не мога да променя voix, защото тази папка се синхронизира с телефона, нека проверим дали voix.ren (директория за преименуваните файлове) съществува, ако не – нека я създадем:

      if [ ! -d "voix.ren" ]; then
           mkdir voix.ren
      fi

Добре де, но нали имаме и входящи и изходящи разговори? Значи е добре да създадем и тяхната структура (нали помните $state?):

      if [ ! -d voix.ren/$state ]; then
           mkdir voix.ren/$state
      fi

А така … сега вече сме готови …

Стъпка 5 – новото име …

След като сме взели всички необходими променливи и сме подготвили структурата, време е да подредим новото име и да преименуваме файловте. Аз лично предпочитам да придам новото име на променлива и после нея на mv, но това си е избор на всеки.

      newname="voix.ren/"$state"/"$year$month$day"-"$hour$minute$second"_"$phn"."$rext
      echo $file" -> "$newname
      mv $file $newname

За на края – целия код:

#/bin/bash
for file in voix/*/*.wav
do
     state=`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
     fi
     if [ ! -d voix.ren/$state ]; then
          mkdir voix.ren/$state
     fi
     newname="voix.ren/"$state"/"$year$month$day"-"$hour$minute$second"_"$phn"."$rext
     echo $file" -> "$newname
     mv $file $newname

done

Вие разбира се може да не го направите така. Както казах – не е красиво. Но е функционално, а на мен ми трябва точно за това – да направи това, което искам от кода. Не искам да прави фокуси или да ми прави кафе. Искам да хване и да преименува едни файлове.

Надявам се съм ви бил полезен.

Ваш,

Lucifer

Вашият коментар

Вашият имейл адрес няма да бъде публикуван. Задължителните полета са отбелязани с *

 

Този сайт използва Akismet за намаляване на спама. Научете как се обработват данните ви за коментари.