2016-03-29 2 views
0

Раньше я попросил некоторую помощь для удаления и замены содержимого файла. С помощью Питера и примера, что проблема была решена (See this post). Однако он создал еще один, этот вопрос связан с удалением строк.Удаление строк между двумя примерами интереса внутри файла в tcl

Так вот вопрос, я могу удалить строки для каждого экземпляра Prefix_1, который появляется в файле.

Однако существуют линии между двумя экземплярами, которые пропускаются (поскольку строка не начинается с Prefix_1), поэтому остается в файле.

Я знаю, что строка начинается с префикса_1, за которой следует точка, а затем имя переменной и заканчивается либо пробелом, либо знаком равенства или двоеточия.

Каждая строка, которая заканчивается двоеточием, имеет связанную с ней таблицу.

Я бы выделил два класса строк, один из которых заканчивается пробелом и знаком равенства, а другой - с двоеточием. Затем, когда обнаруживается двоеточие, удаляется вся строка до обнаружения следующего экземпляра Prefix_1?

Prefix_1.Var1 = -2 
Prefix_1.Var2 = 1 
Prefix_1.Var3: 
    1.1 1.3 1.8 15 1.9 0.1 16 71 31 16 12 1 881 199 19 100 1000 1005 1005 1005 
Prefix_1.Var4 = 1 
Prefix_1.Var5: 
    40 50 75 100 150 
Prefix_1.Var6: 
    4 
    7 
    15 
    25 
    35 
    45 
Prefix_1.Var7: 
    #TABLE 30 2 5 6 
    70  70  70  70  70  100  100 
    81  80  80  100  100  81  80 
    80  100  100  81  80  80  100 
    100  82  81  81  100  100  87 
    87  87 
Prefix_1.Var8 = 1 
Prefix_1.Var9 = 65 
Prefix_1.Var10: 
    255 255 255 255 255 255 255 255 255 255 
Prefix_1.Var11: 
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 6 1 2 2 0 0 0 0 0 0 0 0 
Prefix_1.Var12 = 30 

После того как я удалить все строки с Prefix_1, я до сих пор остались эти строки, которые попадают между двумя экземплярами Prefix_1.

Я хочу их удалить.

1.1 1.3 1.8 15 1.9 0.1 16 71 31 16 12 1 881 199 19 100 1000 1005 1005 1005 
40 50 75 100 150 
4 
7 
15 
25 
35 
45 
#TABLE 30 2 5 6 
70  70  70  70  70  100  100 
81  80  80  100  100  81  80 
80  100  100  81  80  80  100 
100  82  81  81  100  100  87 
87  87 
255 255 255 255 255 255 255 255 255 255 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 6 1 2 2 0 0 0 0 0 0 0 0 
+0

Общая стратегия: Разделить файл на куски, где каждый кусок - это то, что будет сохранено или удалено. Затем для каждого куска решает, сохранить ли его. Стратегия chunking просто не «разделена на отдельные строки» ... –

+0

так что вы, помимо regsub 2 до 999, хотите удалить все данные prefix1, я прав? – Rilwan

+0

Я добавил пример до и после обработки файлов – Anju

ответ

0

(Этот ответ расширяет мой earlier answer here.)

Простой исправление: заменить

default { 
     lappend buf $line 
    } 

с

{^Prefix} { 
     lappend buf $line 
    } 
    default {} 

, если вы используете upvar вариант, или

default { 
     return $line 
    } 

с

{^Prefix_} { 
     return $line 
    } 
    default {} 

иначе.

Это означает, что действие по умолчанию - это пропустить строку, и эти строки будут сохранены, только если они имеют нумерованный префикс, отличный от «Префикс_1».

Это решение не соответствует синтаксису данных в файле, что неудовлетворительно, но если оно работает, оно должно быть достаточно хорошим.

Counting вхождение Prefix_1

Вы можете записать номера строк для первой и последней строки, которая начинается с «Prefix_1», но для этого вам нужно еще больше данных, что является стойким вне команды обработки. Возможно, пора перейти к объектно-ориентированному программированию.

oo::class create LineProcessor { 
    variable first last count buffer 
    constructor args { 
     set first 0 
     set last 0 
     set count 0 
     set buffer {} 
    } 
    method process line { 
     incr count 
     switch -regexp $line { 
      {^Prefix_1\.} { 
       if {$first == 0} { 
        set first $count 
       } 
       set last $count 
       return {} 
      } 
      {^Prefix_2\.} { 
       lappend buffer [regsub 2 $line 999] 
      } 
      {^Prefix_} { 
       lappend buffer $line 
      } 
      default {} 
     } 
    } 
    method dump {} { 
     join $buffer \n 
    } 
    method report {} { 
     puts "First/last line with Prefix_1: $first/$last" 
    } 
} 

LineProcessor create lp 

fileutil::foreachLine line data.txt { 
    lp process $line 
} 
fileutil::writeFile data.txt [lp dump] 
lp report 
# => First/last line with Prefix_1: 1/40 

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

+0

Спасибо, Питер, это работает в некоторой степени. Я думаю, что я могу расширить это немного больше. Кстати, можно ли узнать номер строки в первый раз и последний раз «Префикс_1» происходит в файле? Я могу подсчитать количество раз, когда шаблон имеет место, и общее количество строк в файле, но не может надежно получить первый и последний раз Perfix_1. – Anju

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