LINUX.ORG.RU

Непотоковый редактор bash

 , ,


2

1

Задача: есть текстовый файл, из него необходимо удалить подходящие под условия данные (окружены <>), после удаления необходимо убрать пустые строки (еще лучше было бы заменить двойные переносы одинарными). Вывод просто печатается на экране. Правильно ли я понимаю, что следующий код не работает, потому что sed - потоковый редактор, и выводит пустую строку в любом случае?

#!/bin/bash
sed -e "s/<.*>//g" $1 | sed -e "s/\n+/\n/g"
в какую сторону копать?

Нет, во-первых, ты неправильно убираешь пустые строки. Во-вторых, можно обойтись одним вызовом sed. С телефона писать неудобно, гугли. А ещё первая регулярка у тебя неправильная, гугли про жадность и подумай, на что заменить .* .

DELIRIUM ☆☆☆☆☆ ()
Последнее исправление: DELIRIUM (всего исправлений: 1)

Ну и для тех, кто найдет эту ветку по заголовку, сообщаем, что непоточный старший брат sed’a вполне естесвенно называется ed’ом.

Zmicier ★★★★★ ()
Ответ на: комментарий от quantum_cat

Не всё так просто, во-первых, не обрабатывается случай, когда внутри <> перенос строки. Во-вторых, не заработает, если после удаления всех <> появятся новые пустые строки, в-третьих, по ТЗ не понятно, что делать с вложенными <>.

DELIRIUM ☆☆☆☆☆ ()
Ответ на: комментарий от Zmicier

Два чая этому лорчанину !

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

anonymous ()
Ответ на: комментарий от quantum_cat

Я в курсе, я же ему писал выше:

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

DELIRIUM ☆☆☆☆☆ ()

s/\n+/\n/g

такое есть в sam/ssam, и все равно нужно отдавать отчет, что если пустая певрая - не сработает

еще вариант удалить строки цeликом из пробела/табуляции: «awk NF»

anonymous ()

Для обработки текста предпочитаю перл.

#! /usr/bin/env perl

use strict;
use warnings;

my $fh;

if (@ARGV) {                 # если на входе имя файла,
  open ($fh, "<", $ARGV[0]); # открываем файл,
} else {                     # иначе
  open ($fh, "<-");          # открываем текст, поданный из пайпа
}
undef $/;                    # не считаем \n концом строки
my $xml = <$fh>;             # всё, что мы открыли, кладём одной строкой в переменную
$xml =~ s/<[^<>]*>//g;       # убираем теги
$xml =~ s/(\n+\s*)*\n+/\n/g; # пустые строки и строки с одними пробелами заменяем на один перевод строки
print $xml;                  # выводим, что получилось


Сохраняем как untag.pl, запускаем как perl untag.pl myfile.html, если надо читать из файла, или как cat myfile.html | perl untag.pl, например, если надо читать из пайпа.
Коряво обрабатывает <> внутри <> (например, закомментированный html), но в большинстве случаев достаточно.
Чтобы обрабатывались и юниксовые, и виндовые окончания строк, в регулярках вместо (\n+\s*)*\n+ должно быть ((\r?\n)+\s*)*(\r?\n)+

Если нужды открывать файлы нет, и надо работать только в пайпе, всё ещё проще:
#! /usr/bin/env perl

undef $/;
while(<>){
# ... и дальше тупо любые регулярки в столбик
s/<[^<>]*>//g;
s/(\n+\s*)*\n+/\n/g;
print;
}


Ну и «Регулярные выражения» Фридла почитай хоть несколько глав, пригодится в любом языке, выше не зря про ту же жадность упоминали.

massimus ★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.