2014-12-18 7 views
0

Я хотел бы извлечь из текста:Удалите все строки между рисунком

CHEXA*   99001088  99001001  99001143  99001179*00072A1 
*00072A1  99001047  99001104  99001144  99001180*00072A2 
*00072A2  99001048  99001105         
RBE3*   99001089      99001001    123*00072A5 
*00072A50.11263443595303    123   6001515.041507658257159*00072A6 
*00072A6   60016620.61808377914687    123   6001542 
CHEXA*   99001086  99001001  99001128  99001095*0007299 
*0007299  99001081  99001171        *000729B 
*000729B 

эта часть:

RBE3*   99001089      99001001    123*00072A5 
*00072A50.11263443595303    123   6001515.041507658257159*00072A6 
*00072A6   60016620.61808377914687    123   6001542 

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

CHEXA*   99001088  99001001  99001143  99001179*00072A1 
*00072A1  99001047  99001104  99001144  99001180*00072A2 
*00072A2  99001048  99001105         
CHEXA*   99001086  99001001  99001128  99001095*0007299 
*0007299  99001081  99001171        *000729B 
*000729B 

То, что я попытался было:

sed '/RBE3\*/,/\*/d' 

, но, к сожалению, он остановится после первого появления . Но цель состоит в том, чтобы удалить все строки после выполнения RBE3, который начинается с *, и этот будет удалять только одну строку. Спасибо

ответ

1
import os 

keep = True 
with open(pathToInput) as infile, open(pathToOutput, 'w') as outfile, open(pathToSave) as savefile: 
    for line in infile: 
     if line.startswith("RBE3"): 
      keep = False 
     elif not line.startswith("*"): 
      keep = True 
     if keep: 
      outfile.write(line) 
     else: 
      savefile.write(line) 

os.remove(pathToInput) 
os.rename(pathToOutput, pathToInput) 
+0

Эта работа отлично подходит для удаления линий. Не могли бы вы также добавить часть для сохранения удаленных строк в новом файле.Спасибо – Drago

+0

Легко понять, как писать удаленные строки: с открытым (in_file) как infile, open (out_file, 'w') в качестве outfile, open (out_rbe3, 'w') в качестве outfile1: ' для линии в INFILE: '' если line.startswith ("RBE3"): '' держать = false' 'Элиф не line.startswith ("*"):' ' держать = true' ' если держать: ' ' outfile.write (строка) ' ' else: ' ' outfile1.write (строка) ' – Drago

+0

@Drago: Я отредактировал свое сообщение, чтобы вы могли сохранить данные RBE3. – inspectorG4dget

0

вот регулярное выражение, которое будет работать на Python или PCRE

/(RBE3\*).+(?=CHEXA\*)/s (обратите внимание, что s модификатор требуется для его работы.)

простая реализация Python:

import re 
import os 
inPut = "list" 
outPut = "tmp" 

regexp = re.compile("(RBE3\*).+(?=CHEXA\*)", re.S) 

with open(inPut, 'r') as f: 
    fileStr = f.read() 
match = regexp.search(fileStr).group(0) 
ret = re.sub(regexp, "", fileStr) 
with open(outPut, 'w') as tmpFile: 
    tmpFile.write(match) 
os.remove(inPut) 
os.rename(outPut, inPut) 
0

С awk:

awk -v flag=0 ' 
    /^[^\*]/ { flag = 0 } # clear flag if the line does not start with a * 
    /^RBE3\*/ { flag = 1 } # except if it is the starting line of an ignored block 
    flag == 0 { print } # print if ignore flag is not set. 
    ' foo.txt 

Приятная вещь в том, что он легко расширяется для инверсии. Если вы пишете

awk -v flag=0 -v ignore=0 ' 
    /^[^\*]/ { flag = 0 } 
    /^RBE3\*/ { flag = 1 } 
    flag != ignore { print } 
    ' foo.txt 

затем заменив ignore=0 с ignore=1, вы можете извлечь блок вместо того, чтобы игнорировать его.

1

Через re модуль питона.

import re 
with open('/path/to/the/infile') as infile, open('/path/to/the/outfile', 'w+') as out: 
    foo = infile.read() 
    out.write(re.sub(r'(?s)RBE3\*.*?\n(?!\*)', r'', foo)) 

Обновление:

import re 
with open('/path/to/the/infile') as infile, open('/path/to/the/outfile', 'w+') as out, open('/path/to/the/file/to/save/deleted/lines', 'w+') as save: 
    foo = infile.read() 
    out.write(re.sub(r'(?s)(.*?\n)(RBE3\*.*?\n(?!\*))(.*)', r'\1\3', foo)) 
    save.write(re.sub(r'(?s)(.*?\n)(RBE3\*.*?\n(?!\*))(.*)', r'\2', foo)) 
+0

привет @Avinash Raj. Он отлично работает для удаления линий между рисунком. Но не могли бы вы немного объяснить и добавить часть, чтобы сохранить удаленные строки в отдельном файле. Спасибо – Drago

+0

см. Мое обновление .. –

+0

К сожалению, я получаю ошибку RuntimeError: «Внутренняя ошибка в двигателе регулярных выражений» Не могли бы вы проверить. Спасибо – Drago

0

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

awk '{if(match($0,"RBE3")>0)flag=0}{if(match($0,"CHEXA")>0)flag=1}{if(flag==1) print $0}' File 

выход:

CHEXA*   99001088  99001001  99001143  99001179*00072A1 
*00072A1  99001047  99001104  99001144  99001180*00072A2 
*00072A2  99001048  99001105         
CHEXA*   99001086  99001001  99001128  99001095*0007299 
*0007299  99001081  99001171        *000729B 
*000729B 
0
awk -v key="RBE3" ' 
index($0,key"*")==1 { f=1; print > "newfile" } 
f && /^\*/ { print > "newfile"; next } 
{ f=0; print } 
' file > tmp && mv tmp file 

В приведенном выше примере используется index(), поэтому он выполняет строковое сравнение, а не сравнение с регулярным выражением, поэтому он не будет терпеть неудачу, если ваш ключ содержит метасимволы RE, в отличие от любого решения sed.

Смежные вопросы