Imprime linhas de um arquivo entre dois padrões correspondentes [duplicados]

6

Como posso imprimir todas as linhas entre duas linhas, começando com um padrão para a primeira linha e terminando com outro padrão para a última linha?

Atualizar
Eu acho que foi um erro mencionar que este documento é HTML. Eu pareço ter tocado um nervo, então esqueça isso. Eu não estou tentando analisar HTML ou fazer nada com isso além de imprimir uma seção de um documento de texto.

Considere este exemplo:

aaa
bbb
pattern1
aaa pattern2
bbb
ccc
pattern2
ddd
eee
pattern1
fff
ggg

Agora, quero imprimir tudo entre a primeira instância de pattern1 , começando no início de uma linha, e pattern2 , começando no início de outra linha. Quero incluir as linhas pattern1 e pattern2 na minha saída, mas não quero nada depois da linha pattern2 .

pattern2 é encontrado em uma das linhas da seção. Eu não quero parar por aí, mas isso é facilmente corrigido indicando o início da linha com ^ .

pattern1 aparece em outra linha após pattern2 , mas não quero ver nada disso. Estou apenas procurando por tudo entre a primeira instância de pattern1 e a primeira instância de pattern2 , inclusive.

Encontrei algo que quase me leva até lá usando sed :

sed -n '/^pattern1/,/^pattern2/p' inputfile.txt

... mas isso começa a ser impresso novamente na próxima instância de pattern1

Eu posso pensar em um método usando grep -n ... | cut -f1 -d: duas vezes para obter os dois números de linha, em seguida, tail e head para obter a seção que eu quero, mas estou esperando por uma maneira mais clara. Talvez awk seja uma ferramenta melhor para essa tarefa?

Quando eu começar a trabalhar, espero amarrar isso em um git hook. Eu também não sei como fazer isso, mas ainda estou lendo e pesquisando:)

Obrigado.

    
por Vince 22.02.2016 / 08:39

2 respostas

4

Você pode fazer com que sed saia em um padrão com sed '/pattern/q' , para que você só precise de suas correspondências e saia na segunda correspondência de padrões:

sed -n '/^pattern1/,/^pattern2/p;/^pattern2/q'

Dessa forma, apenas o primeiro bloco será mostrado.

    
por 22.02.2016 / 10:10
3

Como uma abordagem geral, com sed , é fácil imprimir linhas de uma correspondência para outra, inclusive:

$ seq 1 100 > test
$ sed -n '/^12$/,/^15$/p' test
12
13
14
15

Com o awk, você pode fazer o mesmo assim:

$ awk '/^12$/{flag=1}/^15$/{print;flag=0}flag' test
12
13
14
15

Você pode torná-los não inclusivos assim:

$ awk '/^12$/{flag=1;next}/^15$/{flag=0}flag' test
13
14

$ sed -n '/^12$/,/^15$/p' test | sed '1d;$d'
13
14
    
por 22.02.2016 / 09:45

Tags