У меня есть долгий файл журнала, где каждая запись начинается со строки containg только дефисы.
Можно сделать это со сценарием оболочки таким образом:
#!/bin/bash
if [[ -z "$1" ]] ; then
echo Usage: $0 '<inputFile>'
exit 1
fi
line=$(grep -n '^--*$' "$1" | tail -1 | sed 's/:.*//')
if [[ -z "${line}" ]] ; then
cat "$1"
else
sed "1,${line}d" "$1"
fi
Учитывая входной файл:
this is line 1
-------
this is line 3
-------
this is line 5
this is line 6
это производит:
this is line 5
this is line 6
Посредством объяснения, grep -n
производит серию строк как:
2:-------
4:-------
где 2
и 4
номера строки. tail -1
затем просто отфильтровывает все кроме последнего и sed
полосы все от двоеточия в конец строки, оставляя просто номер строки
Затем если не было никаких строк с желаемым шаблоном, он просто производит весь файл. Иначе это удаляет все строки между 1 и последнюю строку дефиса.
Как в стороне, мой исходный ответ включал это awk
отрывок, который обработает файл только однажды:
awk '/^--*$/{s=""}{s=s$0"\n";}END{print s}'
Однако имейте в виду, что это работает путем накопления строк в строку и убирания строки каждый раз, когда это находит строку дефиса. Затем в конце это просто производит строку (все строки после последней строки дефиса).
В то время как на первый взгляд, это, может казаться, более эффективно, это, кажется, не в действительности. В (по общему признанию неисчерпывающих) тестах в моей системе это на самом деле работало вполне немного медленнее, я думаю, чтобы сделать со строкой многих, добавляет продолжение. Факт - то, что решение для сценария, кажется, быстрее несмотря на то, что оно делает несколько передач данных (возможно, потому что каждая передача очень ограничена в том, что оно делает).
Можно также сделать это с sed:
% cat t.txt
this is line 1
this is line 2
-------
this is line 3
----
this is line 4
-------
this is line 5
this is line 6
% sed -n -e '/^---*/{h;d;}' -e H -e '${g;p;}' t.txt
-------
this is line 5
this is line 6
%
(с некоторыми семенами те точки с запятой должны были бы быть новыми строками).
Я думаю, что это может быть легко сделано с помощью sed
. Вы хотите, чтобы команда нашла финал (т.е. в последний раз) строкой единственных дефисов, и Вы хотите p
rint от той точки в конец файла.
К сожалению, я не очень хорош с sed. Надеясь кто-то еще может уточнить.
Править
ХОРОШО, sed
не идеально. Вот то, как сделать это с ex
, близнец только для текста vi
:
ex filename
$
?----------
.,$p
q
Использовать tac
и sed
:
$ cat log-file --- first ------ second --- last $ tac log-file | sed -e '/^-\+$/,$d' | tac last