САС: адресация двух строк перед матчем
Выведите строку, которая находится за 2 строки до соответствия (шаблон).
Я попробовал следующее:
sed -n ': loop
/.*/h
:x
{n;n;/cen/p;}
s/./c/p
t x
s/n/c/p
t loop
{g;p;}
' datafile
6 ответов
Это может работать для вас (GNU sed):
sed -n ':a;$!{N;s/\n/&/2;Ta};/^PATTERN\'\''/MP;$!D' file
Это напечатает строку за 2 строки до PATTERN
по всему файлу.
Сценарий:
sed -n "1N;2N;/XXX[^\n]*$/P;N;D"
работает следующим образом:
- Прочитайте первые три строки в пространство образца,
1N;2N
- Поиск тестовой строки
XXX
где-нибудь в последней строке, и если найдено, выведите первую строку пространства шаблона,P
- Добавить следующую строку ввода в пространство образца,
N
- Удалить первую строку из пространства шаблона и перезапустить цикл без нового чтения,
D
отмечая, что1N;2N
больше не применимо
Этот с grep, немного более простое решение и легко читаемый [Однако нужно использовать один канал]:grep -B2 'pattern' file_name | sed -n '1,2p'
Если вы можете использовать awk
попробуй это:
awk '/pattern/ {print b} {b=a;a=$0}' file
Это напечатает две строки до pattern
Я проверил вашу команду sed, но результат странный (и, очевидно, неправильный), и вы не дали никакого объяснения. Вам нужно будет сохранить три строки в буфере (именуемый удерживающим пространством), выполнить поиск по шаблону с самой новой строкой и напечатать самую старую, если она соответствует:
sed -n '
## At the beginning read three lines.
1 { N; N }
## Append them to "hold space". In following iterations it will append
## only one line.
H
## Get content of "hold space" to "pattern space" and check if the
## pattern matches. If so, extract content of first line (until a
## newline) and exit.
g
/^.*\nsix$/ {
s/^\n//
P
q
}
## Remove the old of the three lines saved and append the new one.
s/^\n[^\n]*//
h
' infile
Предполагаемый и входной файл (infile
) со следующим содержанием:
one
two
three
four
five
six
seven
eight
nine
ten
Будет искать six
и как результат будет давать:
four
Вот еще несколько вариантов:
awk '{a[NR]=$0} /pattern/ {f=NR} END {print a[f-2]}' file
Это хранит все строки в массиве a
, Когда шаблон найден, хранится номер строки магазина.
По окончании выведите номер строки из файла.
PS может быть медленным с большими файлами
Вот еще один:
awk 'FNR==NR && /pattern/ {f=NR;next} f-2==FNR' file{,}
Это читает файл дважды (file{,}
такой же как file file
)
В первом раунде он находит шаблон и номер строки магазина в переменной f
Затем во втором раунде он печатает строку два до значения в f