al_fuhrmann (al_fuhrmann) wrote,
al_fuhrmann
al_fuhrmann

Categories:

Работа с кучей файлов

Вероятно, это не самая удачная запись в теме. Но кому-то может подойти. (Удачная == полезная.) Записи здесь идут в хронологическом порядке и слабо связаны между собой, хотя могут быть и серии записей.


Каждый пользователь – сам себе админ. Давно прошло то время, когда пользователи видели в ПК только пишущую машинку. Число документов у пользователей растет как на дрожжах, даже у школьников. О таких людях как, например, фотографы, и говорить нечего. Иногда бывает нужно привести файлы в порядок. Дело в том, что у простых пользователей, или назовем их домашними пользователями, обычно нет никакой системы в их деятельности. Файлы постепенно накапливаются, но в какой-то момент может возникнуть идея их упорядочения: “вот здесь у меня то, а там это”.

Сам факт владения файлами, да и вообще, любыми предметами, еще мало что значит, если они образуют свалку. В них невозможно найти нужную информацию быстро, особенно, если они не текстовые. В целом, культура владения компьютером подразумевает, что даже имена файлов должны быть информативными и одновременно краткими. Каталоги, которые (к удивлению многих пользователей) тоже являются файлами, не исключение. Каждый пользователь выбирает свою собственную систему имен и отношений между ними (файловую структуру), если только какая-либо программа не навязывает свои собственные правила.

Чтобы компьютеру было легче перечитывать содержимое каталогов, не стоит набивать их огромным множеством файлов. Это здорово замедляет просмотр папок. Файлы всевозможных коллекций лучше собирать в отдельные папки и помещать их в общую. Это удлиняет пути к файлам, вот из каких соображений нужно экономить в названиях. Разумный выбор пользовательской файловой структуры может существенно ускорить работу операционной системы даже на слабом компьютере. Но подобные вещи не могут делаться “автоматом”, так как не существует, и не может существовать операционной системы, которая понимала бы смысл пользовательской деятельности. Следовательно, становится бессмысленным поиск какой-то мудрой “проги”, которая наведет в ваших файлах порядок.

Существует много программ для работы с файлами, как файловых менеджеров, так и более-менее специализированных, “заточенных” под фотографии, музыку и т. п. Но если переименование/перемещение файлов требует каких-то гибких правил, то все эти средства малопригодны. Фильтры и правила для переименования файлов оказываются слишком прямолинейными и примитивными, для их настройки приходится щелкать мышью по кнопкам в разных окнах десятки раз. Но пользователи воспринимают это как должное.

Что станет делать пользователь Windows, если ему потребуется привести в порядок большую коллекцию каких-то файлов, то есть, привести их имена к какой-то системе и разложить по определенным каталогам, основываясь на той информации, которая есть в самих именах файлов? Это будет зависеть от уровня подготовленности пользователя. Те, кого обычно называют “чайниками”, будут вручную переименовывать каждый файл. Если задача включает еще и сортировку по каталогам, то работа станет похожей на перебор риса или крупы. Возможно, здесь появятся, кроме компьютера, и другие канцелярские принадлежности, вроде цветных фломастеров и листов бумаги для заметок. Более продвинутые пользователи используют кое-какие средства для сортировки и массового переименования, какие предлагают файловые менеджеры. Но это, как бы оно не радовало пользователей, лишь ненамного сократит время и объем работы.

Допустим, у нас есть “электронный” комплект подшивок каких-то журналов за десяток лет. Причем, у одной половины из них, или около того, имена файлов образованы по другим правилам, чем у другой. Одна часть придерживается правила HL_mm_yyyy, а другая DL-yyyy-mm – где y – цифры года, а m – цифры месяца. Нам требуется переименовать их по правилу hl-mm-yy, то есть, год сохранить в формате двух последних цифр. Если взять Total Commander то и с ним хлопот не оберешься. Над файлами придется производить множество операций: выделение, какие-то промежуточные переименования, возможно, и перемещение в другие каталоги. Какие бы виртуозные манипуляции при этом не производились, они – все равно – займут немалое время, так как у пользователя могут возникнуть не совсем тривиальные заморочки с сортировкой файлов по именам. Это потребует хитростей, а для рядового пользователя это вовсе непросто. Вот цитата от одной дамы, о Windows Commander'e: “Я попробовала с ним работать, у меня не получилось, и я его сразу возненавидела”.

Прибавим к нашим рассуждениям капельку науки. То есть, просто подсчитаем, сколько времени может занять вся процедура в двух вариантах. В первом, пользователь начального уровня будет тратить на переименование и перемещение файла в нужную папку примерно от 10 до 80 секунд. В среднем 30. Это не арифметическое среднее, потому, что пользователю придется искать файлы по именам вручную. Сортировка, которая так или иначе присутствует в окнах файловых менеджеров, немного ускорит работу, поскольку пользователь будет опираться на видимые закономерности. Так как число документов составляет сотню или около того, то “чистое” время составит: 100*30/60 = час без десяти минут. Если нужно будет еще что-то архивировать, то это потребует добавочного времени и в целом может составить почти час. Еще учтем, что работая такими темпами, пользователь будет просто измочален. Приемлемый вариант – два часа добросовестной работы, полдня офисной, полный рабочий день российско-офисной работы.

Второй вариант, это применение нескольких фильтров и групповых (пакетных) переименований. Их понадобится несколько штук, но “средне-продвинутый” пользователь ставится перед необходимостью решить несколько теоретико-множественных задач. А это, особенно для гуманитариев, “конкретная заморочка”. Чем лучше мы описываем при помощи шаблона имен желаемое множество файлов, тем меньше будет манипуляций. Пользователь, перебирающий файлы, может не подозревать, что он работает с множествами. Но это совсем не облегчает ему работу, ведь он стремится к тому, чтобы компьютер сам переименовал/переместил файлы. Так что, в лучшем случае, работа такого пользователя продлится около 20 минут, вместе с проверкой и исправлением ошибок.

Есть еще один способ, который не потребует никаких “прог” весом в десятки мегабайт. Ничего, кроме текстового редактора, здесь не нужно. Да, это программа, и ее можно увидеть прямо на картинке ниже.

Значок скрипта

Размер сценария (скрипта) всего 401 байт. Это просто несколько строчек текста. Однако они выполняют всю работу, до конца, и без ошибок. Можно заподозрить, что это не Windows, и это правда. Но для Windows тут нет никаких препятствий, так как: 1) можно написать «родной» сценарий для Windows; 2) существует библиотека cygwin.dll (или cygwin1.dll) которая позволит выполнять скрипты оболочки UNIX в Windows.

Алгоритм, понятный любому пользователю, состоит в том, что у каждого файла нужно взять из его имени кусочки, соответствующие месяцу и году, образовать из них новое имя и скопировать файл с новым именем в отдельную папку. Затем в этой папке можно создать архивы в духе годовой подшивки. Это уменьшит число файлов и ускорит доступ к ним. Это все понятно, но технические детали: как объяснить все это компьютеру, простому пользователю не очень понятны. И какой же тогда компьютер “автомат”, если пользователю приходится почти все делать вручную?

“Автомат” тратит на все это не слишком много времени, и это время можно довольно точно оценить:

Запуск с часами

Минута и две секунды. Смысл этих команд в том, что мы записываем текущее время в файл, который называется out, и тут же запускаем “автомат”. Сразу после того, как он отработает, мы добавляем текущее время снова. И тут же просим систему вывести файл out на экран. Можно было бы просто выполнить ./cvt, но тогда время пришлось бы оценивать “на глазок”.

Сам скрипт выглядит так:

Код

Одна “прога” создает при помощи еще одной “проги” третью, которая отработав, будет выброшена, а первая доведет дело до конца. Не кривя душой, большинство согласится, что результат “вчепятляет”.

И устроено все это не слишком сложно. Можно просто рассказать, что делает каждая из этих строчек.

1. Здесь “волшебная” строка #! – означает, какая программа дальше будет иметь дело с этим файлом. В нашем случае это bash (Bourne Again SHell – “еще одна оболочка Борна”). Стивен Борн написал командный интерпретатор, который затем был возрожден Брайаном Фоксом для GNU. В Linux используется повсеместно, фактически стандарт.

2. Такую же строку мы вписываем при помощи эха в новый файл, который называется script. Это название, как и все имена файлов, не является догмой. Нам этот файл еще будет нужен. Здесь стоит обратить внимание на то, что строки обычно закавычиваются одиночными или двойными кавычками. Это дает оболочке понять, что пробелы тоже являются частью строки.

3. Создаем новый каталог с именем hl. Сюда мы поместим упорядоченные копии файлов.

4. А это поинтереснее. Это конвейер (pipeline, pipe – трубопровод, труба) – одна программа пишет свой вывод прямо на ввод другой программы. Вертикальная черта служит признаком этого. Команда ls выводит список файлов в текущем каталоге. А вот awk – это уже целый язык программирования. Ахо, Вайнбергер и Керниган создали очень неплохой инструмент для обработки текста. Программа awk (точнее, ДЛЯ awk) также взята в тексте нашего сценария в кавычки, чтобы шелл передал ее всю целиком. Редактор gedit подсвечивает синтаксис в зависимости от языка программирования. Так вот, желтым у нас как раз выделена программа для awk. Она начинается с шаблона (pattern). Шаблон ограничен двумя слэшами / /. А за шаблоном идет блок инструкций в фигурных скобках. Таков основной синтаксис awk-скрипта. Если строка соответствует шаблону, блок инструкций выполняется, иначе awk ищет следующий шаблон для той же строки. В шаблонах могут быть использованы как обычные, так и регулярные выражения. Если шаблона нет – блок инструкций применяется к каждой строке. По умолчанию строка просто печатается.

Небольшая справка о регулярных выражениях, только минимум. В нашем случае оно содержится внутри / … /. Регулярное выражение состоит из обычных символов (совпадающих с собой) и метасимволов. Метасимволы в таком контексте имеют особое значение. Мы используем два метасимвола (на самом деле их немного побольше): точку и звездочку. Звездочка имеет значение: “любой символ из того же класса что и непосредственно перед звездочкой, в количестве от нуля и до скольких угодно”. Точка: “любой одиночный символ”. Так что наше регулярное выражение соответствует: HL, HL_, HL__ и т. п. Эта небольшая неточность не влияет на дальнейшее поведение программы. Фактически мы ищем файлы с префиксом только HL_

Не парьтесь с пониманием всего сразу. Понимайте, что сможете, а остальное обязательно поймете позже.

5, 6. Эти строки потрясающе похожи, так что мы можем их рассмотрение объединить. Как мы уже знаем, предыдущая строка начинает блок кода, который будет обрабатывать строки, передаваемые по конвейеру от ls. Это будет последовательность имен файлов в каталоге.

Каждая очередная строка целиком находится в специальной переменной $0. Переменная m по нашему замыслу должна хранить номер месяца, который входит в имя файла. y – соответственно, год. Суть в том, что у нас есть много файлов, имена которых записаны в формате: HL_mm_yyyy.djvu, например: HL_12_2006.djvu Что это за файлы, неважно, но нам надо только, чтобы их имена были переписаны как hl-mm-yy.djvu, например: hl-12-06.djvu Для этого мы должны сделать кое-какие перестановки символов, запоминая некоторые из них в отдельных переменных, а затем комбинируя их по-новому.

Для этого в awk есть функция substr (substring). Пятая строка, например, у нас имеет следующий смысл: нужно взять из входной строки ($0), начиная с ее четвертой позиции, два символа, и поместить их в переменную m. Нетрудно прикинуть, что это как раз номер месяца. С шестой строкой мы имеем то же самое, но только там год, в формате двух последних цифр.

7. А это строка, которая у нас производит сборку выводимой строки. Мы хотим получить ее в виде команды для той же оболочки. (Программа делает программу.) Здесь мы имеем смесь в виде строковых констант и переменных. Составленные вплотную, они образуют итоговую строку. Зная это правило, легко не путаться в кавычках, а именно:

"cp "$0 – даст в результате “cp что-то” если в $0 хранится “что-то”.

И так далее. Следом за каждой парой кавычек используется содержимое той или иной переменной. Таким образом, оператор print будет знать, что ему печатать. Ну, и наконец, закрывающая фигурная скобка завершает блок инструкций.

8. Начинается совершенно аналогичный блок для очередного шаблона. У нас есть файлы, названные по немного другим правилам: DL-2006-12.djvu Отличие только в порядке следования года и месяцев. Стало быть, нужно лишь чуть изменить аргументы в обращениях к функциям substr.

9, 10. Полностью аналогичны строкам 5 и 6.

11. Здесь мы просто дописываем в файл script очередную сформированную строку. awk перебирает все строки, поступающие по конвейеру от ls. Таким образом, ни один файл, соответствует он шаблонам или нет, не останется незамеченным.

12. Мы делаем файл script исполняемым. Команда chmod (CHange MODe – дабы не было понято превратно) изменяет права доступа. 700 – означает просто, что: владелец файла может делать с ним все, что угодно, например, запускать как программу, а все остальные не могут даже прочитать его (а зачем?).

13. Несчастливое число! Но именно в этой строке script и запускается на выполнение. А чтобы bash знал, что это именно в данном каталоге запускается исполняемый файл, мы используем ./ (точку и слеш). Например, наш главный скрипт назван cvt. Между тем, команда cvt уже есть в системе, и без уточнения ./cvt будет запущена системная, что нам совсем не нужно. Кстати script выполняется довольно долго, с полминуты, так как файлы, которых много, из предосторожности не перемещаются (mv), а именно копируются.

14. Удаляется ненужный файл script, мавр сделал свое дело.

15. Мы переходим в ранее созданный каталог hl, куда уже были скопированы файлы с новыми именами. Предстоит немного еще в нем поработать.

16. Здесь мы готовим цикл. Переменная i будет последовательно получать значения, прописанные вручную после in. Все, что справа от in, образует массив значений. Так как мы НЕ используем здесь кавычки, то получим именно массив, а не один элемент массива. Так что, вы должны уловить разницу между использованием и неиспользованием кавычек.

17. Начало цикла.

18. Здесь то, что происходит в цикле. Это заслуживает внимательного рассмотрения. Во-первых, команда, используемая в теле цикла, никуда не записывается, поэтому никаких кавычек здесь нет. Во-вторых, это уже не awk, а оболочка. Поэтому нам следует ставить знак доллара каждый раз, когда мы хотим обратиться к содержимому любой переменной. У оболочки такое правило.

Команда tar (Tape ARchive – ленточный архив) записывает файлы в один большой файл, правда, без сжатия (cf – создать архив и добавить в него файлы) . Мы уже можем предвидеть, какие это будут имена: hl-06.tar, hl-07.tar и т. д. Остальные файлы в этой командной строке формируются передачей строки из конструкции $( … ) Это означает, что команды в круглых скобках будут запущены в еще одной копии оболочки, а вывод будет подставлен в конец формируемой строки. Раньше использовался немного другой синтаксис: ` `. Его и сейчас можно использовать, но он плохо читается и может приводить к ошибкам.

В скобках: команда ls выполняется в каталоге hl а grep будет пропускать только те файлы, которые образованы по правилу: если в i находится, к примеру, значение 06, то будут выбраны только файлы: hl-01-06..., hl-02-06..., hl-ab-06... но всегда с 06 в позициях 7 и 8. Ключ -e при вызове grep подскажет этой утилите, что шаблон является именно регулярным выражением, а не чем либо другим. В нашем случае, это единственный пример настоящего регулярного выражения. Предыдущее (использованное в awk) было обычным выражением. Но, надеюсь, вы уже представляете себе, что регулярные выражения – довольно мощная штука.

Что касается сжатия архивов, то в данном случае это дурная работа, формат djvu и так уже сжат весьма неплохо.

19. Эта строка показывает, что надо вернуться к началу цикла и посмотреть, есть еще итерации, или уже все.

20. Наконец мы удаляем из каталога hl ненужные файлы.

И вот что мы получаем в результате:

Архивы

Мы можем убедиться, что в архивах все в порядке:

Архив внутри

Внимательный наблюдатель может заметить, что у нас не файла hl-07-12.djvu. Но тот же внимательный наблюдатель заметит, что у нас есть файл DL-2012-06-07.djvu на самом первом рисунке. “”Два в одном“”. Наверняка читатели, не являющиеся админами или программистами, имеют уже кое-какие идеи по использованию таких скриптов. Если найдется хотя бы пара человек, которые почувствуют желание перейти в Linux и немного поизучать работу в терминале, то автор сочтет свою цель достигнутой. Пишите в комментариях, не стесняйтесь.

Так чем же лучше программы с кучей окон и кнопок? Разве они позволят задать такие гибкие правила для выполняемых действий? И чем лучше Windows со всей ее необыкновенной тупизной? Для выполнения проделанной работы оконную программу в Windows пришлось бы перезапускать не один раз, ожидая каждого результата для продолжения работы. Машина под Windows – это даже не машина, а стиральная доска.

В действительности, скрипт содержал не два фильтра-шаблона, а почти полторы дюжины с разнообразными вариантами, 98% из чего удалось поставить на “автомат”. Потому, что на самом деле “описабельных” подмножеств среди файлов было много, и для каждого из этих подмножеств предназначалась своя папка или архив. Автор просто использовал для этого поста “сырую версию”, запущенную для проверки работоспособности. Я не знаю, сколько работала полная версия скрипта: пять, семь, десять минут. Да мне это было и не интересно, так как я спокойно спал. А кто-то вкалывал всю ночь до утра, как папа Карло...

Дальше
Tags: файлы
Subscribe

  • Снайперский прицел (+бонус)

    Для поиска в интернете. Дикая вещь!! Пригодится всем, кто ищет информацию. Без всякой рекламной херни и гнилых ссылок. Однако, как говорил один мой…

  • Xcircuit - 1

    Хочу рассказать о хорошем редакторе приципиальных схем. Как видно из названия, этот редактор сделан для X (только не надо путать это с десяткой), и…

  • Вдогонку к предыдущему посту

    Конечно, такой навороченный инструмент, как Meshlab, не может не содержать множество кнопочек и крутилок для поддержания нормального полета. Только…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments