Как извлечь отдельные абзацы из текста, используя Vim? - PullRequest
4 голосов
/ 15 февраля 2012

Я пытаюсь извлечь тест из огромного файла, содержащего текст в этом формате, несколько раз

CL blahblahblah  
SP blahblahblah blahblahblah blahblahblah  
DE blahblahblahblahblahblah blahblahblah blahblahblah   
   blahblahblah blahblahblah blahblahblah blahblahblah  
AB blahblahblah blahblahblah blahblahblah 
   blahblahblahblahblahblah blahblahblah blahblahblah
   blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah    
   blahblahblah blahblahblah blahblahblah   
C1 blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah 
   blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah   
   blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah 
   lahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah 
RP blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah
   blahblahblah blahblahblah  
EM blahblahblah blahblahblah blahblahblah blahblahblah  
NR blahblahblah blahblahblah blahblahblah blahblahblah  
TC blahblahblah blahblahblah blahblahblah blahblahblah 
   blahblahblah blahblahblah blahblahblah blahblahblah  
Z9 blahblahblah blahblahblah blahblahblah blahblahblah  
PU blahblahblah blahblahblah blahblahblah blahblahblah  
PI blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah  

Меня интересуют только записи, начинающиеся с C1, AB, TI, но иногда они охватывают несколько строк, а следующие за ними XX строки тегов не всегда совпадают. Есть ли простой способ сохранить только эти записи? Так что мой оставшийся текст должен быть таким:

TI blahblahblah  
AB blahblahblah b lah blahblah blah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah     
C1 blahblahblah blahblahblah blahblahblah blahblahblah  
   blahblahblah blahblahblah blahblahblah blahblahblah  
   blahblahblah blahblahblah blahblahblah blahblahblah 
TI blah blah blah blah blah blah  
AB blahblahblah blahblahblah blahblahblah blahblahblahblahblahblah blahblahblah blahblahblah blahblahblah blahblahblahblah blahblahblah blahblahblah blahblahblah   
   blahblahblah blahblahblah blahblahblah blahblahblah  blahblahblah blahblahblah blahblahblah blahblahblah 
   blahblahblah blahblahblah blahblahblah blahblahblah 
C1 blahblahblah blahblahblah blahblahblah blahblahblahblahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah 

и пр.

Большое спасибо!

Ответы [ 5 ]

3 голосов
/ 15 февраля 2012

awk решение:

awk '
BEGIN{
    tags["C1"]
    tags["AB"]
    tags["TI"]
}
{
    match($0, /^\w+/)
    if(RSTART)
        t=substr($0, RSTART, RLENGTH)
}
t in tags' input.txt

Перевести на vim команду:

:g/^/let t=matchstr(getline('.'), '^\w\+') | if !empty(t) | let tag=t | endif | if index(['C1', 'AB', 'TI'], tag)==-1 | d | endif
3 голосов
/ 15 февраля 2012

Я бы сделал:

:$put='X' | 1,$-1g/^\(\s\|C1\|AB\|TI\)\@!/   ,/^\S/-d
:$d

Это сделает следующее:

  • Вставьте строку, содержащую «X» в конце
  • для каждой строкикроме последнего (1,$-1), если он начинается с непробела и не начинается с C1, AB или TI (g/pattern/), удаляйте (d) до следующей строки, не начинающейся с пробела ,/pattern/, не включенного (- что сокращенно от -1)
  • удалить строку «X» в конце

Чтобы попытаться использовать Gvim:

  • скопируйте этот код в буфер обмена
  • в Gvim run :@+ (который воспроизводит команды Ex из регистра +, который связан с буфером обмена).

What Iполучил:

AB blahblahblah blahblahblah blahblahblah 
   blahblahblahblahblahblah blahblahblah blahblahblah
   blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah    
   blahblahblah blahblahblah blahblahblah   
C1 blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah 
   blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah   
   blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah 
   lahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah 
3 голосов
/ 15 февраля 2012

Это должно работать:

:let @a="" | g/^\v<(C1|AB|TI)>/norm! "Ay/^\S^M

РЕДАКТИРОВАТЬ Для Windows: вам нужно добавить 'return' в эту строку, введите ^M как Cq Введите (или C-v, если вы не используете Windows или ваш vimrc не устанавливает behave mswin)

Получает строки в регистр "a.Чтобы заменить буфер этими строками:

:%d | put a

Или поместите его в новый буфер:

:new | put a
2 голосов
/ 15 февраля 2012

Это работает, но в конце файла остается пустая строка.

:%s/\v^(C1|AB|TI|\s)@!\_.{-}\n(C1|AB|TI|$)@=//

Это регулярное выражение использует несколько хитрых функций, я попытаюсь объяснить.

  • \v говорит, что шаблон "очень волшебный", просто позволяет нам пропустить обратную косую черту в нескольких местах.
  • ^(C1|AB|TI|\s)@! соответствует любой строке, которая не начинается с целевых тегов или пробелов.
  • \_. соответствует любому символу, включая символы новой строки.
  • {-} соответствует предыдущему атому как можно меньше раз (без жадности).
  • \n соответствует концу строки.
  • (C1|AB|TI|$)@= соответствует целевым тегам или концу строки (для конечного случая) с нулевой шириной.

Результат с вашим тестовым вводом следующий:

AB blahblahblah blahblahblah blahblahblah
   blahblahblahblahblahblah blahblahblah blahblahblah
   blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah
   blahblahblah blahblahblah blahblahblah
C1 blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah
   blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah
   blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah blahblahblah
0 голосов
/ 15 февраля 2012

другой лайнер awk:

awk -F' |\t' '{if($1)f=$1~/CI|AB|C1/?1:0}f' yourFile
...