Кое что о SED

В жизни любого айтишника, бывают моменты, когда нужно сделать много однообразной работы, но инструментами, которые могли бы помочь автоматизировать процесс не владеешь. И тут возникает вопрос, что быстрее: потратить время, научиться пользоваться инструментом, и потом сделать все за 5 минут, или потратить время и сделать все в ручную.

Зачастую, сделать в ручную быстрее, если конечно не думать о том, что возможно придется еще не раз делать эту работу, а обычно так и бывает!

Так случилось, что сегодня мне нужно было в пяти мегабайтном CSV файле из почти 100 000 строк заменить сперва все запятые на точку с запятой, а затем все точки на запятые. Не буду вдаваться в подробности, но сперва, я попробовал как обычно открыть его в Libre  Office Calc. Точнее открыл то я его без проблем, а вот операция “поиск с заменой” подвесила редактор на долго. Прождав минут 10, я его прибил. Решил, что старый добрый nano сделает это быстрее. Хрен там было!

Любой смыслящий в линукс, скажет – в SED это сделать легко, но так уж вышло, что для меня SED это тот самый инструмент, который изучить все не доводилось. Но решил попробовать. Нашел довольно хороший мануал для новичков, и блин эта ацкая прога перемолола файл примерно за 2 СЕКУНДЫ!!!!

Сказать что я был удивлен – ничего не сказать. Я сперва подумал, что команду не правильно ввел…. Но все было верно. Ниже перепост того мануала. Автору ОГРОМНОЕ СПАСИБО. Ссылка на оригинал в конце.

Чтобы правильно использовать этот инструмент нужно понять его философию и назначение. Нужно определить его область применения и очертить круг задач, которые он позволяет решать. Для ответа на этот вопрос нам нужно совершить небольшое погружение в проблему.

Вообще, потоковый редактор (не только sed) предназначен для автоматической обработки текстовых файлов. Хорошо, но что значит «обработка»? Давайте прикинем — какие вообще могут быть обработки текста?

Ну, первое, что приходит на ум — это замена слов. Это раз.

Далее. Поскольку редактор sed обрабатывает текст порциями, а порцией считается одна строка (которая заканчивается символом «новая строка»), то — редактор должен уметь заменять целые строки. Это два.

Хорошо. А еще что-нибудь можно нагрузить на потоковую обработку текста?

Ну, наверно, сюда можно было бы отнести также удаление строк и вставку новых строк. Это три и четыре.

Этого функционала для работы нам, пожалуй, хватит! То есть, это почти все основные действия, которые мы хотим получить от потокового редактора.

Таким образом, мы можем начать изучение редактора sed не с ознакомления и заучивания его ключей и параметров, а несколько необычным методом. Давайте представим, что мы сами сейчас изобретаем (создаем) потоковый редактор с нуля.

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

— замена указанного слова (s, от «substitude» — подстановка):
— удаление строки (d, от «delete» — удалить), на которую укажем;
— вставка строки до (i, от «insert» — вставить) и добавление строки после (a, от «append» — добавить) указанной;
— заменить указанную строку (c, от «change» — замена);

Это основные команды. На самом деле sed может выполнять больше команд, но нам сейчас важно начать работать с ним, а не иметь исчерпывающие мертвые знания.

Таким образом, на данный момент мы уже примерно знаем чего можно, а чего нельзя требовать от sed.

Теперь давайте попрактикуемся.
Подстановка

Давайте в качестве подопытного текста возьмём сказку про Колобка и заменим слово «Колобок» на слово «Кирпич». Для этого выполним следующую команду:

$ sed s/Колобок/Кирпич/g fairytale.txt > new-fairytale.txt

Итак, что мы тут имеем. (Пристегните ремни, ибо логика команд редактора sed — это что-то! Но к счастью, этого сумасшествия не так много. Терпите!)

Мы видим, команду s (substitude, замена), далее следует символ ‘/’. Это символ-разграничитель полей. Первое поле — слово «Колобок» — это то, что мы ищем в тексте. Следующее поле — слово «Кирпич» — это то, чем мы будем заменять слово из первого поля.

После этих полей следует символ g. Это — флаг «global», который сообщает редактору, что следует производить замены всех слов «Колобок», которые присутствуют в строке, на слово «Кирпич». Если этот флаг не указывать, то sed произведет замену первого встретившегося слова «Колобок» и перейдет к следующей строке, и если в этой строке присутствуют еще слова «Колобок», то они останутся нетронутыми. Но это не наш вариант. Нам интереснее заменить все слова, поэтому указываем флаг.

Если вместо флага g написать цифру, то sed будет искать в строке слово из перового поля, подсчитывать их не изменяя — но произведет замену лишь только того слова, порядковый номер которого соответствует цифре.

Например, у нас в строке 15 раз встречается слово «Колобок.» И если мы вместо флага g укажем цифру 8, то только восьмое по счету слово «Колобок» будет заменено на слово «Кирпич». Остальные слова останутся нетронутыми.

На этом допустимые флаги не исчерпываются. Но я не хотел бы сейчас чрезмерно углубляться в подробности. Поэтому продолжаем дальше анализ команды.

Мы видим, что далее в командной строке идет имя файла — fairytale.txt. Это ни что иное как имя исходного файла, над которым мы производим манипуляции.

По умолчанию sed направляет результат своих преобразований в стандартный выход (то есть в консоль). При необходимости мы можем перехватить вывод и направить его в файл, что мы и сделали с помощью конструкции «> new-fairytale.txt«.

Вообще надо отметить, что многие утилиты в Линуксе не изменяют исходных файлов, а результат выводят на консоль. Такой подход гарантирует безопасность операций — если внезапно что-то пойдет не так, то вы ничего не сломаете. Пользуйтесь этой особенностью!
Удаление строки

Потоковый редактор sed позволяет удалять не только одну строку (это банально!), а целый диапазон строк.

Так, например, команда

$ sed ’15d’ fairytale.txt

удалит пятнадцатую строку. Полученный текст (без 15-ой) строки будет выведен на терминал. Можете проверить. Как я уже обращал ваше внимание выше — sed не изменяет исходный текст. Не поленитесь, потренируйтесь! И опять же, при необходимости полученный результат можно сохранить в файле.

Следующая команда

$ sed ‘20,40d’ fairytale.txt

удалит сразу 21 строку — с 20-ой по 40-ю включительно.

Можно удалить все строки — начиная с указанно и до конца файла. Для этого вместо второй цифры в команде нужно поставить знак доллара:

$ sed ’20,$d’ fairytale.txt
Вставка и добавление строки

Команды Вставка и Добавление строк очень похожи друг на друга — и та, и другая добавляют строку в текст. Разница состоит в том, что «Вставка» вставляет строку перед указанной строкой, а «Добавление» — добавляет после указанной строки. Осталось понять, что такое указанная строка и как ее указать.

Да очень просто! Например, эта команда вставляет строку «А ну-ка, тетя, подвинься!» перед третьей строкой текста:

$ sed ‘3i\А ну-ка, тетя, подвинься!’ fairytale.txt

Грубо говоря, был текст такой:
1
2
3
4

Шаланды полные кефали
В Одессу Костя приводил,
И все бендюжники вставали,
Когда в пивную он входил.

А стал такой:
1
2
3
4
5

Шаланды полные кефали
В Одессу Костя приводил,
А ну-ка, тетя, подвинься!
И все бендюжники вставали,
Когда в пивную он входил.

А если вместо «вставки» выполнить «добавление»:

$ sed ‘3a\А ну-ка, тетя, подвинься!’ fairytale.txt

, то получим
1
2
3
4
5

Шаланды полные кефали
В Одессу Костя приводил,
И все бендюжники вставали,
А ну-ка, тетя, подвинься!
Когда в пивную он входил.
Замена строки

Тут тоже все просто. Вместо указанной строки нам нужно влепить другую. Например, команда

$ sed ‘3c\Дирекция охрану вызывала,’ fairytale.txt

Выдаст на консоль следующий «выхлоп»:
1
2
3
4

Шаланды полные кефали
В Одессу Костя приводил,
Дирекция охрану вызывала,
Когда в пивную он входил.

И, пожалуй, на этом изучение sed мы закончим.

\\ОТСЮДА: http://zhevak.wordpress.com/2013/11/26/%D0%BA%D0%B0%D0%BA-%D0%BD%D0%B0%D1%87%D0%B0%D1%82%D1%8C-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%83-%D1%81-%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%B2%D1%8B%D0%BC-%D1%80%D0%B5%D0%B4%D0%B0%D0%BA%D1%82%D0%BE/

Добавить комментарий

Войти с помощью: