Bashня

Пишем сценарии на Bash

Скачивал я как-то из интернета книгу для офлайновой работы. По иронии судьбы, это было Advanced Bash-Scripting Guide. Книга была в виде кучки файлов HTML, а скачивал я её на работе, небезызвестной программой Teleport Pro. При скачивании побилась информация о кодировке (в теге meta указано utf-8, на самом деле файлы в koi-8r). Принудительного задания кодировки в Teleport Pro я не нашёл (возможно, плохо искал, да и занимать дефицитное время интернет-станции не хотелось...).

На помощь пришёл сам bash. Собственно, выходов два: либо перекодировать каждый из 102 файлов iconv-ом, либо поменять указание на кодировку в мета-теге каждого файла. Я выбрал второй путь.

Сценарий запускается в папке с обрабатываемыми файлами. Обработанные скидываются в папку corrected.


#!/bin/bash
mkdir corrected
for file in *
do
  echo "$file"
  sed s/utf-8/koi8-r/ "$file" > ./corrected/"$file"
done

В предыдущем случае все обрабатываемые файлы лежали в одном каталоге. Чуть более сложный случай - файлы раскиданы по дереву. Тогда имеет смысл воспользоваться командой find. У неё много ключей, но простейший случай - поиск по имени, find - n.

В очередной версии МСВС приплыла обновлённая версия rpmbuild, где немного поломали формат spec-файлов для rpm-пакетов. Обязательный ранее тег Copyright стал недопустимым, вместо него появился новый обязательный тег License.

Вообще-то, это свинство. Могли просто объявить Copyright устаревшим, но поддерживать его для совместимости. Ну ладно, запускаем сценарий и переименовываем. После этого можно запускать сборку пакетов и радоваться жизни.


#!/bin/bash
echo Ищем файлы
FILES=`find -name *.spec`
for file in $FILES
do
  echo "$file"
  sed s/Copyright/License/ "$file" > "$file".new
  rm "$file"
  rename spec.new spec "$file".new
done

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

Простейшее применение:

wc -l *

Если нужен не "столбик" по всем файлам, а только итоговая сумма, лучше использовать wc в сочетании с cat:

cat * | wc -l

Наконец, если нужен рекурсивный подсчёт (с учётом файлов в дочерних каталогах), можно использовать команду find:

find * -exec cat {} \; | wc -l

Более сложный вариант от ScorpioN-а:

find * \( -name "*.cpp" -o -name "*.h" \) -type f -exec cat {} \; | wc -l

Здесь игнорируются записи о каталогах (просто предупреждений будет меньше, и отбираются только файлы .h и .cpp)

Подобным образом считается количество байт в файлах...

find * -exec cat {} \; | wc -c

...и самих файлов:

find * | wc -l

Раз мы заговорили о find, напомню, что у find есть множество ключей, позволяющих ограничить критерии поиска (а то вдруг вам не все файлы нужно включить в подсчёт...)

Например, эта команда удалит из репозитария Subversion все файлы с расширением .ui.h (полезно при завершении перевода проекта Qt3 на Qt4).

find -name *.ui.h -exec svn rm {} \;

А вот пример посложнее. Предположим, у нас скопилось большое количество исходных текстов, частично написанных в CP1251, частично в KOI8-r. Преобразуем их в UTF8.

Ключ -name можно не задавать и вместо двух команд дать одну, но процесс будет на несколько секунд подлиннее. Нам же не надо обрабатывать Qtшные файлы ui - они уже в правильной кодировке.

find . -type f -name *.h -exec bash -c "enca -x utf-8 {}" \;

find . -type f -name *.cpp -exec bash -c "enca -x utf-8 {}" \;

Автоопределением здесь занимается команда enca. В Астралинуксе она есть "из коробки", в других дистрибутивах её, возможно, придётся поставить из репозитариев. Более "стандартной" командой для перекодирования в никсах является iconv, но к сожалению, автоопределения в ней не предусмотрено.

Иногда бывает, что несколько кодировок перепутаны в ОДНОМ файле - тогда увы... В этом случае enca скорее всего честно выведет предупреждение, что не может определить кодировку, и оставит их в покое. (Если кодировки везде опознаются нормально, то команда в традициях unix way отработает молча.)

М.З., 03.02.2012 - 14.01.2015
Viewable With Any Browser Пишите! В начало Designed by
Arachnophilia
Designed by Arachnophilia 4.0