Форум программистов, компьютерный форум, киберфорум
Наши страницы

Потоковый редактор sed: Разбор примеров

Войти
Регистрация
Восстановить пароль
Заберите себе весь мир, оставте мне один компьютер.
Оценить эту запись

Потоковый редактор sed: Разбор примеров

Запись от nezabudka размещена 19.01.2018 в 23:01

Потоковый редактор sed дает власть над текстовыми файлами.
Имеются много примеров по sed в интернете с описанием результата
вывода демонстрируемых примеров. Можно конечно бездумно копировать
подобные наработки но понимание сути происходящего как раз и отличает
пытливого человека от остального мира юзеров.
Я решила время от времени писать однострочные скрипты с описанием
происходящих процессов в этом замечательном потоковом редакторе.
Такие примеры по моему мнению будут подходящим подспорьем по изучению
языка программирования sed. Что бы понимать то, что я здесь буду
описывать необходимо ознакомиться для начала например с учебником
на русском языке в переводе и с добавлениями от drBatty по этой
ссылке маленький учебник по sed

Реверс строк файла
Bash
1
sed -n '1!G;$p;$!h' text.txt
Первая строка загружается в буфер (основной буфер),
игнорируя команду G которой соответствуют все строки кроме первой 1! и
команду $p поскольку она нацелена только на последнюю строку $.
По команде h содержимое области удержания (вспомогательный буфер)
заменяется содержимым буфера, опция -n подавляет автоматический вывод
на печать содержимого буфера.
Вторая строка загружается в буфер, команда G добавляет знак
перевода строки и содержимое области удержания к содержимому буфера. В
результате в буфере находятся 2 строки, первая и вторая разделенные
знаком перевода строки. (к такому буферу применимы команды в многострочном
режиме при добавлении мидификаторов m,M). Опять пропускаем адресную команду $p.
Далее последней в скрипте командой h заменяем содержимое области удержания
содержимым буфера, тоесть записываем в область удержания две строки разделенные
знаком перевода строк. И так далее до последней строки...
Загружаем в буфер последнюю строку. Командой G добавляем к ней
знак переноса строки и следом дописываем содержимое области удержания,
а он содержит все строки файла, кроме последней, разделенные знаком переноса строк.
В итоге у нас вместо последней строки в буфере находятся все строки файла
разделенные знаком переноса строки.
Следующая адресная команда $p срабатывает, так как адрес ее как раз
и является последней строкой файла. Эта команда выводит на печать буфер
обходя опцию -n подавляющую вывод. Но так как буфер в многострочном режиме
выводит на печать строки разделенные знаком перевода строки с права на лево,
то мы получим на выходе реверс строк по отношению к исходному файлу.
Последняя адресная команда $!h не выполняется, потому что адресом ее являются
все строки кроме последней $!. Кстати адрес в этой команде можно было бы опустить
без ущерба для результата, так как она без адреса всего лишь записывает также
и последнюю строку включительно, тоесть содержимое буфера записывается
в область удержания уже не влияя на вывод. На этом работа редактора заканчивается.

Удалить вторую по счету строку из найденных в которой присутствует запятая
Bash
1
sed '/,/! b;x;s/$/\n/;/^\n\{2\}$/d;x' text.txt
Отфильтровываем с помощью регулярного выражения /,/! строки без запятой
и отправляемся по команде безусловного перехода b в конец скрипта, тоесть игнорируем
все последующие команды и оставляем содержимое буфера в неизменном
для вывода виде. При поступлении на вход строки в которой присутствует запятая,
игнорируется команда b по шаблону /./! и первой начинает выполнятся
команда x которая просто меняет местами содержимое области удержания
и содержимое буфера. Область удержания инициализирована изначально
знаком конца строки $. В результате обмена в буфере оказывается
якорь переноса строки $ который при выводе буфера на печать
заменяется знаком перевода строки. Команда l дает нам возможность посмотреть,
что же мы имеем в буфере.
Bash
1
sed '/,/! b;x;l;x' text.txt
Мы увидим вывод содержимого файла и перед строчками содержащими запятую
дополнительные строки с якорем переноса строки $ выводимый из области.
По команде замены s/$/\n/ в конец строки (изначально пустой)
втавляем символ переноса строки (может быть употреблен любой символ
не используемый в тексте файла, но выбор \n является оправданным, так как
он при загрузке строк просто отбрасывается и в процессе внутренних операций
не используется). В итоге через команду l получим следующие строчки в выводе
Bash
1
sed '/,/! b; x;s/$/\n/;l;x' text.txt
Перед первой встретившейся строчкой со знаком запятая увидим строку
с одним символом переноса строки \n$, перед второй строкой содержащей
запятую увидим уже два символа \n\n$ и так далее. Получается
мы организовали счетчик строк содержащих запятую. Этот счетчик
мы не увидим на выходе без команды l потому что последней командой
в цепочке идет еще одна команда x которая ждет когда команда s/$/\n/ добавит
к счетчику очередной символ перевода строки и вернет строку обратно
в область удержания, а помещенную первой командой x строку содержащую запятую
из области удержания переместит в буфер. Нам остается только перед последней
командой x вставить последовательность s/^\n\{2\}/d блокирующую вывод
буфера со строкой по счету совпадающей с количеством символов
перевода строки /^\n\{2\}$/. Стоит заметить что хотя перед выводом
буфера содержимое области удержания и буфера меняются местами
но блокировка текущей строки происходит после выполнения всех команд в скрипте,
в частности блокировка буфера происходит уже после выполнения последней команды x
меняющей содержимое буфера и области удержания.
Размещено в Без категории
Просмотров 282 Комментарии 0
Всего комментариев 0

Комментарии

 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru