Imprimir linhas entre (e excluindo) dois padrões


13

Vou enviar um formulário usando cURL, onde parte do conteúdo vem de outro arquivo, selecionado usando sed

Se o param1padrão de correspondência de linha de outro arquivo estiver usando sed, o comando abaixo funcionará bem:

curl -d param1="$(sed -n '/matchpattern/p' file.txt)" -d param2=value2 http://example.com/submit

Agora, vá para o problema. Quero mostrar apenas texto entre 2 padrões correspondentes, excluindo o padrão correspondente.

Vamos dizer que file.txtcontém:

Bla bla bla
firstmatch
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.
secondmatch
The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.

Atualmente, muitos sedcomandos "entre 2 padrões correspondentes" não serão removidos firstmatche secondmatch.

Eu quero que o resultado se torne:

It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.

Respostas:


15

Aqui está uma maneira de fazer isso:

sed '1,/firstmatch/d;/secondmatch/,$d' 

Explicou: A partir da primeira linha para a linha correspondente firstmatch , excluir. Da linha que corresponde à segunda correspondência até a última linha, exclua.



5

A outra sedsolução falhará se firstmatchocorrer na 1ª linha 1 .

Mantenha a simplicidade, use um intervalo único e um regex 2 vazio :
imprima tudo nesse intervalo, exceto as extremidades do intervalo (impressão automática desativada) 3 :

sed -n '/firstmatch/,/secondmatch/{//!p;}' infile

ou, mais curto, exclua tudo que não estiver nesse intervalo e também exclua o término do intervalo:

sed '/firstmatch/,/secondmatch/!d;//d' infile


1: A razão é que, se o segundo endereço for uma regexp, a verificação da correspondência final começará com a linha que segue a linha que corresponde ao primeiro endereço .
Portanto, /firstmatch/nunca é avaliado para a 1ª linha da entrada, sedsimplesmente a exclui, pois corresponde ao número da linha 1,/RE/e passa para a 2ª linha, onde verifica se a linha corresponde/firstpattern/

2: Quando um REGEX está vazio (ou seja //) sedse comporta como se o último REGEX usado no último comando aplicado (como um endereço ou como parte de um comando substituto) tivesse sido especificado.

3: a ;}sintaxe é para sedimplementações modernas ; com os mais velhos, use uma nova linha em vez do ponto-e-vírgula ou expressões separadas, por exemplosed -n -e '/firstmatch/,/secondmatch/{//!p' -e '}' infile


Você pode explicar o que //está fazendo (dentro da {…})?
G-Man diz 'Reinstate Monica'

Obrigado, mas você caiu na minha armadilha. Eu sei que //significa a última expressão regular usada; de tudo o que li, deveria ser /secondmatch/. Eu verifiquei através de testes que seu comando funciona e, portanto, concluí que ele está funcionando como /firstmatch|secondmatch/(que você confirmou), mas não consigo encontrar nenhuma documentação (nem mesmo o documento POSIX ao qual você vinculou ou o GNU manual sed ) que descreve esse comportamento. … (Continua)
G-Man diz 'Restabelecer Monica'

(Continua) ... Experiências divertidas: (I) Em sed: (1) Se sim /first/,4, então //age como /first/. (2) Se sim 2,/second/, //obtém um erro "sem expressão regular anterior". (Acho isso uma falha flagrante em seguir o comportamento especificado.) (3) A adição --posixnão muda nenhuma das opções acima. (II) Em outros programas: (4) Em vi, depois /first/,/second/, //age como /second/(e as outras formas também são implementações racionais da regra documentada). … (Continua)
G-Man diz 'Restabelecer Monica'

(Continua)… (5)  awkparece não ter noção do “último ER usado”; //refere-se ao não caractere antes ou depois de qualquer caractere. (Convido você a tentar echo -- | awk '{ gsub(//, "cha"); print }'.)
G-Man diz 'Reinstate Monica'

Então, você leu “o último REGEX usado no último comando” como “o último REGEX usado no último comando” e, portanto, você (corretamente) adivinhou que isso significava /first|second/. Sortudo. Menciono os outros programas para demonstrar que essa não é uma convenção regex em todo o sistema. Quem quer que o tenha adicionado sednão se preocupou em adicioná-lo vim, onde teria feito quase tanto sentido. :-) ⁠
G-Man diz 'Reinstate Monica'
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.