2013-10-05 1 views
2

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

1  
2  
3  
4  
5  
6  
7  
8 

и удалить из вторая линия до третьей линии предыдущей последней, чтобы получить:

1  
2  
6  
7  
8 

Заранее благодарен!

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

+0

Для этого вам не нужен sed: 'awk 'NR <= 2 {print} {for (i = 3; i> = 2; - i) x [i] = x [i-1]; x [1] = $ 0;} END {для (i = 3; i> = 1; - i) print x [i]} '' – SheetJS

+0

Хорошо выглядит ... но ... вместо цифр, как можно Я использую его с текстовыми строками? –

+0

Он работает со всеми типами строк: '$ 0' - это вся строка – SheetJS

ответ

3

Getting количества строк с wc и использованием awk для печати требуемого диапазона:

$ awk 'NR<M || NR>N-M' M=3 N="$(wc -l file)" file 
1 
2 
6 
7 
8 

Это позволяет легко изменять диапазон, просто изменяя значение M.

+0

Спасибо, это работает! –

1

Использование :

sed -n ' 
    ## Append second line, print first two lines and delete them. 
    N; 
    p; 
    s/^.*$//; 
    ## Read next three lines removing leading newline character inserted 
    ## by the "N" command. 
    N; 
    s/^\n//; 
    N; 
    :a; 
    N; 
    ## I will keep three lines in buffer until last line when I will print 
    ## them and exit. 
    $ { p; q }; 
    ## Not last line yet, so remove one line of buffer based in FIFO algorithm. 
    s/^[^\n]*\n//; 
    ## Goto label "a". 
    ba 
' infile 

Это дает:

1 
2 
6 
7 
8 
+0

Большое спасибо, но это тихое грязное –

2

поскольку вы упомянули огромные, а также номера строк могут быть отличаются. Я хотел бы предложить эту AWK Однострочник:

awk 'NR<3{print;next}{delete a[NR-3];a[NR]=$0}END{for(x=NR-2;x<=NR;x++)print a[x]}' file 
  • он обрабатывает входной файл только один раз, без (предварительно) расчет общего числа строк
  • он хранит минимальные данные в памяти, во все времена обработки, только Были сохранены 3 строки данных.
  • Если вы хотите изменить критерии фильтрации, например, удалив из строки x значение $-y, вы просто просто измените смещение в oneliner.

тест:

kent$ seq 8|awk 'NR<3{print;next}{delete a[NR-3];a[NR]=$0}END{for(x=NR-2;x<=NR;x++)print a[x]}' 
1 
2 
6 
7 
8 
+0

Спасибо ... это работает ... но это немного путают –

+0

@DavidAlejandro, если производительность не является проблемой, использование 'wc -l' для вычисления номера строки было бы проще. Это решение поддерживает только 3 строки в буфере и распечатывает их в конце. – Kent

+0

To downvoter: вы добавите какое-то объяснение, почему ответ так плох? Я рад узнать. – Kent

3

Это может работать для вас (GNU СЭД):

sed '3,${:a;$!{N;s/\n/&/3;Ta;D}}' file 

или я е вы предпочитаете:

sed '1,2b;:a;$!{N;s/\n/&/3;Ta;D}' file 

Они всегда печатаются первые две строки, а затем построить бегущую окно из трех линий. Если конец файла не достигнут, первая строка выскочит из окна и удалилась. В конце файла выводятся остальные 3 строки.