n=$some_num
{ head -n"$(($(wc -l <in)-n))" >/dev/null
grep 'match your string'
} <in
Infelizmente, isso requer a leitura do arquivo inteiramente por meio de w / wc
para obter uma contagem de linhas, porque não está claro o contrário quantas linhas estão no arquivo ou qual é o tamanho $n
. Além disso, essa deve ser uma solução com muito desempenho, desde que <in
seja um arquivo regular, lseek()
able .
Primeiramente, obtemos nossa contagem de linha e subtraímos $n
dela. head
lê muitas linhas de stdin e grava os resultados em /dev/null
. O que sobra depois são $n
-count linhas de entrada em stdin e apenas seu grep
e seu padrão.
Tecnicamente isso engana - há um pipe na substituição de comando para wc
. É minha esperança que você possa ignorar isso.
A propósito, outra maneira de fazer isso pode parecer:
{ grep "-m$n" 'some pattern near yours' >/dev/null
grep 'your pattern'
} <in
... com um% GNUgrep
. Se você puder grep
$n
ocorrências de outro padrão que o colocará na vizinhança de seu padrão de destino, você poderá realmente fazê-lo sem um pipe.
Eu tentei ficar com grep
, mas aqui está uma solução sed
de qualquer maneira. Os canais abaixo são apenas para entrada - e grep
não está envolvido em todos os trechos para prefixar números de linha para que você possa ver quais números eles são. Tudo isso é apenas para o caso de exemplo. Você pode usar o script sed
sozinho com um arquivo nomeado ou stdin de qualquer tipo e definir $pat
e $n
apropriadamente e ele funcionará.
Eu na verdade apenas reescrevi isso porque eu não gostava de não ser capaz de ancorar as partidas. Isso é um pouco mais lento - não notavelmente, e ainda é muito rápido, mas para cada linha intermediária em buffer ele corta todo o espaço padrão e isola a primeira linha no buffer. Dessa forma, todas as expressões âncoras normais funcionam como esperado.
pat=man n=40
man man |
grep -n ''|
sed -e:B -e'${/^\n/D' \
-eh -e's/\n.*//' \
-e"/$pat/p;x" \
-e\} -e'$D;N;$bB' \
-e"$n,$ D;bB"
648: /etc/man_db.conf
649: man-db configuration file.
651: /usr/share/man
652: A global manual page hierarchy.
654: /usr/share/man/index.(bt|db|dir|pag)
657: /var/cache/man/index.(bt|db|dir|pag)
661: apropos(1), groff(1), less(1), manpath(1), nroff(1), troff(1), whatis(1),
662: zsoelim(1), setlocale(3), manpath(5), ascii(7), latin1(7), man(7), cat-
663: man(8), mandb(8), the man-db package manual, FSSTND
680: developing and maintaining man-db.
Aqui está outro exemplo, mas em um arquivo:
pat=. n=15
seq 100 >nums
sed -e:B -e'${/^\n/D' \
-eh -e's/\n.*//' \
-e"/$pat/p;x" \
-e\} -e'$D;N;$bB' \
<nums -e"$n,$ D;bB"
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100