Aqui está um exemplo de como isso pode ser feito com sed
:
srch_rng(){
set '[:blank:]' "$1" '\
'; sed -n " /^\(.*\n\)*[$1]*$2/,\$!{N
s/^\(\([$1]*\)[$1]*[^$1].*\n\)\([^$1]\)//
s/^/$3/;D
}; /./!p;//!d;H;x
/^\n[$1]*/!h;s///p;t
s/\([$1]*\).*\n//;/^[$1]/p
//!q;x;s/\n.*//;h"
}
Isso funciona em ambos os lados de um intervalo - até que sed
corresponda ao padrão dado como seu primeiro argumento, a partir de stdin
, ele reterá na memória até o recuo de nível superior encontrado. Depois de corresponder ao primeiro argumento, ele não armazena nada além do recuo.
Antes de fazer a correspondência, ele trabalha em um ciclo de extração da linha N
ext, tentando s///
ubstitutar todo o espaço padrão se a última linha puxada for aberta com menos ou igual à mesma quantidade de espaço em branco como a primeira linha em seu buffer seguido imediatamente por um caractere não em branco, em seguida, retornando em loop para descobrir se ele fez uma correspondência para a linha mais recente ou se deve tentar novamente.
Depois de fazer a correspondência, ele primeiro imprime tudo o que reteve até o momento, apaga-a e, no próximo ciclo, e a partir dela, exclui todos, exceto o espaço em branco à direita. Durante o restante de seu tempo de execução, ele continua imprimindo cada linha à medida que a lê até encontrar outra linha que abre com um valor menor ou igual ao nível de recuo armazenado - momento em que sai completamente da entrada.
Dessa forma, ele mantém seus buffers como atuais (e como vazios) , pois pode e não desce a menos que haja trechos muito longos entre os recuos de nível superior antes que ele possa corresponder ao padrão. Ele também não se importa com linhas em branco intervenientes - a informação impressa pode abranger os limites de parágrafo, mas não abrangerá os recuos de nível superior.
Portanto, por exemplo, se eu fizer apenas srch_rng Cell
, ela será impressa da linha Cell 13
para a próxima Cell
. Ele também fará isso se eu especificar ESSID
como o primeiro argumento, mas se eu fizer isso:
srch_rng '.*selma'
... imprime ...
Cell 14 - Address: 90:F6:52:90:C2:2F
Channel:6
Frequency:2.437 GHz (Channel 6)
Quality=21/70 Signal level=-89 dBm
Encryption key:on
ESSID:"selma"
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 6 Mb/s
9 Mb/s; 12 Mb/s; 18 Mb/s%
O .*
é necessário porque o padrão é corresponder apenas aos primeiros caracteres não-brancos em uma linha. E, como você pode ver, para cada linha que imprime, ela remove apenas o espaço em branco que armazenou no buffer de cada uma delas - o que coloca a primeira linha impressa na extremidade esquerda e todas as outras uniformemente abaixo.