sed - imprimir e ramificar

3

Eu tenho um fluxo de entrada contendo strings representando os tipos de arquivo. Eu quero imprimir todos os tipos de arquivo que não são texto ou são PostScript (PostScript é um tipo de arquivo de texto). Eu tentei a seguinte expressão sed:

sed -n '/PostScript/pb; /text/!p'

No entanto, isso retorna um erro:

sed: -e expression #1, char 14: extra characters after command

Isso é confuso para mim porque achei aceitável especificar vários comandos (por exemplo, bp ) após um padrão.

Eu posso obter o comportamento desejado usando a seguinte expressão:

sed -n '/PostScript/p; /PostScript/b; /text/!p'

Como posso obter o comportamento desejado sem duplicar o padrão /PostScript/ em minha expressão?

    
por jayhendren 18.05.2015 / 20:33

2 respostas

3

A maneira comum de obter um grupo de comandos executados juntos (por exemplo, sujeito a uma condição como uma correspondência de padrão) é agrupá-los com chaves.
Com o GNU sed :

sed -n '/PostScript/{p; b}; /text/!p'

Sem agrupamento e com qualquer ramificação sed no final do script nos dois casos e exclua as outras linhas:

sed -e '/PostScript/b' -e '/text/!b' -e 'd'

Além disso, para o registro:

I thought it was acceptable to specify multiple commands (e.g. bp) after a pattern.

Editar comandos para um endereço (o que você chama de padrão é um endereço de contexto) é uma coisa e as bandeiras s ubstitution g , p , w e no. são outra coisa.

A sintaxe para o último é

s/pattern/replacement/[flags]

em outras palavras, os sinalizadores podem ser combinados (por exemplo, gp ou 7w outfile ), enquanto a sintaxe para o primeiro é

[2addr] {editing command
editing command
...
}

em outras palavras, os comandos devem ser separados por novas linhas (em alguns casos, podem ser separados por ponto e vírgula).

    
por 18.05.2015 / 21:07
3

POSIXly:

$ sed -n '/PostScript/p; //b
/text/!p'

POSIX define que, se a expressão regular estiver vazia, sed se comportará como se o último RE usado no último comando aplicado.

Com o seu comando, você precisa de ; entre p e b para fazê-lo funcionar com o GNU sed:

$ sed -n '/PostScript/p; //b; /text/!p'

Com o POSIX sed, você não pode usar //b; porque ; é um nome de ramificação válido. Você precisa usar newline como terminator entre o comando.

    
por 18.05.2015 / 20:44

Tags