sed pattern matching

1

Recentemente, perguntei a alguém no trabalho sobre como obter a saída de ipcs -qa e torná-lo delimitado por espaço, para que eu possa analisá-lo / armazená-lo no banco de dados para monitoramento. Ele me deu isso:

ipcs -qa | sed 's/ [ ]* / /g'

Funciona, mas por quê? Como ele construiu essa string padrão? Onde posso encontrar documentação sobre como construí-los? Eu chequei a página man, mas é bem opaca.

    
por paulrehkugler 26.04.2012 / 17:50

3 respostas

2

Primeiro, tudo isso também parece funcionar bem:

sed 's/[ ]*  / /g'
sed 's/  [ ]*/ /g'
sed 's/ *  / /g'
sed 's/  * / /g'
sed 's/   */ /g'
sed 's/  \+/ /g'
sed 's/ \+ / /g'

Basicamente tudo o que ele faz é combinar 2 espaços, além de qualquer número de espaços consecutivos. Isso funciona porque o regex é ganancioso por padrão, então "qualquer número" é o máximo que ele pode encontrar. (E [ ] é um "match any of these" com apenas um caractere de espaço listado)

A sintaxe específica usada na pergunta é ideal simplesmente porque você está lidando com espaços:

sed 's/ [ ]* / /g'

Não há dois caracteres espaciais adjacentes, portanto, é fácil ver rapidamente que há três espaços, e menos provavelmente será interpretado como um erro de digitação.

    
por 26.04.2012 / 18:16
5
sed 's/ [ ]* / /g'
\_/  | \____/ | |
 |   |    |   | \- g=globally (not just one occurence)
 |   |    |   |
 |   |    |   \- to
 |   |    |
 |   |    \- from
 |   |
 |   \- s=substitute
 |
 \- program sed

O da parte:

/ [ ]* /
| \_/| 
|  | \- repeated 0-infinite times
|  |
|   \- group of characters
|
\- boundary

Incluindo o *, existem 3 quantificadores:

  • 0 até o infinito ? 0 ou 1 vezes
  • 1 a infinito

Eles normalmente se referem apenas ao último caractere, então x * corresponde a x, xxxx e nada. x? corresponde a 0 ou 1 x, + corresponde a x, xx, xxx e assim por diante. Mas pode corresponder a um grupo de caracteres como [aeiou] + ou uma combinação, encapsulada em parens: (foo) *. O primeiro corresponde a iiaiaei, o segundo foo e foofoo.

Um grupo pode ser uma enumeração [aeiou] ou um grupo de para: [a-z] ou uma combinação: [0-9a-fA-F:]. Se você gosta de incluir o menos no grupo, você deve colocá-lo no final ou no começo: [- ,:].

O comando mais usado provavelmente é 'substituto'. Outros são 'd' para excluir e 'p' para impressão.

Padrões são encapsulados entre delimitadores, normalmente barra.

 sed 's/foo/bar/' 

Sed trabalha em linha orientada. Se você gosta de substituir um (o primeiro) foo por bar, o comando acima está ok. Para substituir tudo, você precisa de 'g' para globalmente.

 sed 's/foo/bar/g' 

Outras maneiras de trabalhar com números de linha de chamada do sed:

 sed -n '1,5p' file 

-n não será impresso por padrão, 1,5p significa: imprimir da linha 1 a 5.

 sed '6,$d' file 

Isso é equivalente. Ele irá deletar da linha 6 para o final.

 sed '5q' file

é novamente o mesmo: saia depois da linha 5.

Normalmente, para sed, os comandos são mais fáceis de escrever do que de ler.

    
por 26.04.2012 / 19:10
2

A melhor instrução sed de todos os tempos.

sed 's/ [ ]* / /g'

substituirá todas as duas ou mais seqüências de espaços em um espaço, portanto todas as palavras serão delimitadas por espaço.

    
por 26.04.2012 / 17:56