Как игнорировать все строки перед совпадением в bash?
Я бы проигнорировал все строки, которые встречаются перед совпадением в bash (также игнорируя совпадающую строку. Пример ввода может быть
R1-01.sql
R1-02.sql
R1-03.sql
R1-04.sql
R2-01.sql
R2-02.sql
R2-03.sql
и если я сопоставляю R2-01.sql
в этом уже отсортированном входе, я хотел бы получить
R2-02.sql
R2-03.sql
Ответы
Ответ 1
Много способов. Например: если ваш вход находится в list.txt
PATTERN="R2-01.sql"
sed "0,/$PATTERN/d" <list.txt
потому что 0,/pattern/
работает только на GNU sed (например, не работает на OS X), вот подделка решения.;)
PATTERN="R2-01.sql"
(echo "dummy-line-to-the-start" ; cat - ) < list.txt | sed "1,/$PATTERN/d"
Это добавит одну пустую строку в начало, поэтому реальный шаблон должен быть в строке 1 или выше, поэтому 1,/pattern/
будет работать - удаление всего из строки 1 (фиктивный) до шаблона.
Или вы можете печатать строки после шаблона и удалять 1-й, например:
sed -n '/pattern/,$p' < list.txt | sed '1d'
с awk, например:
awk '/pattern/,0{if (!/pattern/)print}' < list.txt
или мой любимый используйте следующую команду perl:
perl -ne 'print unless 1../pattern/' < list.txt
удаляет строку 1., когда шаблон находится на первой строке...
другое решение - обратное-удаление-обратное
tail -r < list.txt | sed '/pattern/,$d' | tail -r
если у вас есть команда tac
, используйте вместо tail -r
. Интересная вещь, чем /pattern/,$d' works on the last line but the
1,/pattern/d` не на первом.
Ответ 2
Как игнорировать все строки перед совпадением в bash?
Заголовок вопроса и ваш пример не совсем совпадают.
Распечатайте все строки из "R2-01.sql" в sed
:
sed -n '/R2-01.sql/,$p' input_file.txt
Где:
-
-n
подавляет печать пространства шаблонов в stdout
-
/
запускает и завершает шаблон, соответствующий (регулярное выражение)
-
,
отделяет начало диапазона от конца
-
$
обращается к последней строке ввода
-
p
перекликается с пространством шаблонов в этом диапазоне до stdout
-
input_file.txt
- это входной файл
Распечатайте все строки после "R2-01.sql" в sed
:
sed '1,/R2-01.sql/d' input_file.txt
-
1
обращается к первой строке ввода
-
,
отделяет начало диапазона от конца
-
/
запускает и завершает шаблон, соответствующий (регулярное выражение)
-
$
обращается к последней строке ввода
-
d
удаляет пространство шаблонов в этом диапазоне
-
input_file.txt
- это входной файл
- Все, что не удалено, отражается на stdout.
Ответ 3
awk -v pattern=R2-01.sql '
print_it {print}
$0 ~ pattern {print_it = 1}
'
Ответ 4
Это немного взломанный, но его легко запомнить для быстрого получения нужного вам результата:
$ grep -A99999 $match $file
Очевидно, вам нужно выбрать значение для -A
, которое будет достаточно большим, чтобы соответствовать всему содержимому; если вы используете слишком маленькое значение, вывод будет отключен без пауз.
Чтобы обеспечить получение всех результатов, вы можете сделать:
$ grep -A$(cat $file | wc -l) $match $file
Конечно, в этот момент вам может быть лучше с решениями sed
, так как они не требуют двух чтений файла.
И если вам не нужна соответствующая строка, вы можете просто передать эту команду в tail -n+1
в пропустить первую строку вывода.
Ответ 5
вы можете сделать это, но я думаю, что jomo666 ответ был лучше.
sed -nr '/R2-01.sql/,${/R2-01/d;p}' <<END
R1-01.sql
R1-02.sql
R1-03.sql
R1-04.sql
R2-01.sql
R2-02.sql
R2-03.sql
END
Ответ 6
Perl - это еще один вариант:
perl -ne 'if ($f){print} elsif (/R2-01\.sql/){$f++}' sql
Чтобы передать в regex как аргумент, используйте -s
, чтобы включить простой парсер аргументов
perl -sne 'if ($f){print} elsif (/$r/){$f++}' -- -r=R2-01\\.sql file