Usando awk
ou sed
como posso selecionar linhas que estão ocorrendo entre dois padrões de marcador diferentes? Pode haver várias seções marcadas com esses padrões.
Por exemplo: Suponha que o arquivo contenha:
abc
def1
ghi1
jkl1
mno
abc
def2
ghi2
jkl2
mno
pqr
stu
E o padrão inicial é abc
e o padrão final é mno
Então, eu preciso da saída como:
def1
ghi1
jkl1
def2
ghi2
jkl2
Estou usando o sed para corresponder ao padrão uma vez:
sed -e '1,/abc/d' -e '/mno/,$d' <FILE>
Existe alguma maneira sed
ou awk
fazê-lo repetidamente até o final do arquivo?
awk '/abc/{a=1}/mno/{print;a=0}a' file
.awk '/abc/{a=1} a; /mno/{a=0}' file
- com isso, colocando aa
condição antes de/mno/
avaliarmos a linha como verdadeira (e imprimi-la) antes de definira=0
. Desta forma, podemos evitar escreverprint
.awk '/abc/,/mno/' file
awk '/abc/{flag=1}/mno/{flag=0}flag' file
deve fazer.awk 'flag; /PAT1/{flag=1; next} /PAT1/{flag=0}' file
daria.Usando
sed
:o
-n
opção significa não imprimir por padrão.O padrão procura por linhas que contenham apenas just
abc
-justmno
e depois executa as ações no{ ... }
. A primeira ação exclui oabc
linha; o segundo amno
linha; ep
imprime as linhas restantes. Você pode relaxar as expressões regulares, conforme necessário. Quaisquer linhas fora do intervalo deabc
..mno
simplesmente não são impressas.fonte
-e
sed
deve ser executado. Se você quiser ou precisar usar vários argumentos para incluir o script inteiro, deverá usar-e
antes de cada argumento; caso contrário, é opcional (mas explícito).d
a todas as linhas até a primeira partida e depoisd
a todas as linhas que começam com a segunda partida?Isso pode funcionar para você (GNU sed):
Exclua todas as linhas, exceto aquelas entre as linhas inicial
abc
emno
fonte
!d;//d
golfs 2 caracteres melhor :-) stackoverflow.com/a/31380266/895245{//!b}
impede que oabc
emno
sejam incluídos na saída, mas eu não consigo descobrir como. Você poderia explicar?//!b
lê se a linha atual não é uma das linhas que correspondem ao intervalo, quebra e, portanto, imprime essas linhas, caso contrário todas as outras linhas são excluídas.golfs dois caracteres melhor do que ppotong
{//!b};d
As barras vazias indicam
//
: "reutilizar a última expressão regular usada". e o comando faz o mesmo que o mais compreensível:Este parece ser POSIX :
fonte
A partir dos links da resposta anterior, o que fez por mim, rodando
ksh
no Solaris, foi o seguinte:1,/firstmatch/d
: da linha 1 até a primeira vez que você encontrarfirstmatch
, exclua./secondmatch/,$d
: desde a primeira ocorrência desecondmatch
até o final do arquivo, exclua.fonte
1,
) vem antes/firstmatch/
? Eu estou supondo que isso também poderia ser redigido'/firstmatch/1,d;/secondmatch,$d'
?fonte
algo assim funciona para mim:
file.awk:
usando:
awk -f file.awk data
...edit: O_o solução fedorqui é muito melhor / mais bonita que a minha.
fonte
if (record=1)
deve serif (record==1)
, ou seja, duplo=
- veja operadores de comparação gawkResposta de Don_crissti de Mostrar apenas texto entre 2 padrões de correspondência ?
que é muito mais eficiente que o aplicativo da AWK, veja aqui .
fonte
Tentei usar
awk
para imprimir linhas entre dois padrões enquanto pattern2 também corresponde a pattern1 . E a linha pattern1 também deve ser impressa.por exemplo, fonte
deve ter uma saída de
Onde pattern1 é
package BBB
, pattern2 épackage \w*
. Observe queCCC
não é um valor conhecido, portanto não pode ser literalmente correspondido.Nesse caso, nem o @scai
awk '/abc/{a=1}/mno/{print;a=0}a' file
nem o @fedorquiawk '/abc/{a=1} a; /mno/{a=0}' file
funcionam para mim.Finalmente, eu consegui resolver isso
awk '/package BBB/{flag=1;print;next}/package \w*/{flag=0}flag' file
, hahaUm pouco mais de esforço resulta em
awk '/package BBB/{flag=1;print;next}flag;/package \w*/{flag=0}' file
imprimir também a linha pattern2, ou seja,fonte