Удалите строки, которые являются между данными шаблонами из файла (использующий инструменты Unix)

У меня есть текстовый файл (более правильно, “немецкий стиль “файл CSV, т.е. разделенная от точки с запятой, десятичная запятая), который имеет дату и значение измерения на каждой строке.
Существуют фрагменты дефектных значений, которые я хочу удалить перед дальнейшей работой. Я хотел бы сохранить, они включают некоторый сценарий так, чтобы мои исправления были зарегистрированы, и я могу воспроизвести те исправления при необходимости.

Строки похожи на это:

28.01.2005 14:48:38;5,166
28.01.2005 14:50:38;2,916
28.01.2005 14:52:38;0,000
28.01.2005 14:54:38;0,000
(long stretch of values that should be removed; could also be something else beside 0)
01.02.2005 00:11:43;0,000
01.02.2005 00:13:43;1,333
01.02.2005 00:15:43;3,250

Теперь я хотел бы сохранить список, начинают и заканчивают шаблоны как 28.01.2005 14:52:38 + 01.02.2005 00:11:43, и сценарий сократил бы строки, соответствующие, они начинают/заканчивают пар и все, что это между ними.

Я думаю о взламывании awk сценария, но возможно я пропускаю уже существующий инструмент.

7
задан Robert Harvey 31 August 2010 в 15:03
поделиться

5 ответов

Взгляните на sed:

sed '/start_pat/,/end_pat/d'

удалит строки между start_pat и end_pat (включительно).

Для удаления нескольких таких пар можно комбинировать их с несколькими опциями -e:

sed -e '/s1/,/e1/d' -e '/s2/,/e2/d' -e '/s3/,/e3/d' ...
21
ответ дан 6 December 2019 в 09:20
поделиться

вы также используете awk

awk '/start/,/end/' file
0
ответ дан 6 December 2019 в 09:20
поделиться

Во-первых, зачем тебе вести учет того, что ты сделал? Почему бы не сохранить резервную копию оригинального файла, или не сделать различия между старыми и новыми файлами, или не поставить его под контроль исходников?

Для фактических изменений я предлагаю использовать Vim.

Команда Vim :global (сокращенно :g) может быть использована для выполнения :ex-команд на строках, которые совпадают с регексом. Это во многом мощнее, чем awk, так как команды могут ссылаться на диапазоны относительно соответствующей строки, плюс в вашем распоряжении полная вычислительная мощность Vim.

Например, это сделает что-то близкое к тому, что вы хотите (непроверенное, поэтому предостерегайте emptor):

:g!/^\d\d\.\d\d\.\d\d\d\d/ -1 write tmp.txt >> | delete

Это соответствует строкам, которые НЕ начинаются с даты (! отрицает соответствие), добавляет предыдущую строку в файл tmp.txt, затем удаляет текущую строку.

Вы, вероятно, получите дубликаты строк в tmp.txt, но их можно удалить, пропустив файл через uniq.

.
0
ответ дан 6 December 2019 в 09:20
поделиться

Я бы серьезно посоветовал изучать основы perl (т.е. не OO вещи). Это отплатит вам ведром.

Быстро и просто написать немного perl, чтобы сделать это (и многие другие подобные задания), как только вы усвоили основы, которые, если вы привыкли использовать awk, sed, grep и т.д. довольно просты.

Вам не придётся запоминать, как использовать множество различных инструментов, а там, где раньше вы бы использовали несколько инструментов, объединённых в конвейер для решения проблемы, вы можете просто использовать один скрипт на perl (обычно выполняется гораздо быстрее).

И, теперь perl установлен практически на каждом unix/linux дистрибутиве.

(этот sed аккуратный, хотя :-)

.
0
ответ дан 6 December 2019 в 09:20
поделиться

используйте grep -L (не вывести ни одной совпадающей строки)

Извините - вы думали, что вам просто нужны строки без 0,000 в конце

-1
ответ дан 6 December 2019 в 09:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: