Usando sed para remover um colchete de abertura e fechamento ao redor de uma corda


18

Estou executando este comando em um shell bash no Ubuntu 12.04.1 LTS. Eu estou tentando remover os personagens [e de ]uma só vez, ou seja, sem ter que ir para a segunda vez.

Eu sei que colchetes têm um significado especial em uma regex, por isso estou escapando deles acrescentando uma barra invertida. O resultado que eu esperava era apenas a corda, 123mas os colchetes permanecem e eu adoraria saber o porquê!

~$ echo '[123]' | sed 's/[\[\]]//'
[123]

O que estou tentando conseguir é atribuir o que estiver entre colchetes a uma variável bash para uso em outro lugar no meu script bash, portanto, se houver uma maneira melhor de conseguir isso (usando awk, talvez?), Informe-me. .
Xhantar

2
Basta adicionar como um comentário: Você pode usar o recurso de PE da festa como em: str='[123]'; str1=${str/\[/}; str2=${str1/\]}; echo $str2
Valentin Bajrami

1
@ val0x00ff - Substituição pura do bash .. obrigado! :) Aprendi algo novo.
Xhantar

Respostas:


24

Isso é fácil, se você seguir atentamente o manual : todos os membros de uma classe de personagem perdem um significado especial (com algumas exceções). E] perde seu significado especial se for colocado em primeiro lugar na lista. Experimentar:

$ echo '[123]' | sed 's/[][]//g'
123
$

Isto diz:

  1. dentro dos [colchetes] externos , substitua qualquer um dos caracteres incluídos, a saber:
    • ] e
    • [
  2. substitua qualquer um deles pela sequência vazia - daí a sequência de substituição vazia //,
  3. substitua-os em qualquer lugar ( globalmente ) - daí a final g.

Novamente, ] deve ser o primeiro da classe sempre que incluído.


11

Não sei por que isso não funciona, mas o seguinte:

echo '[123]' | sed 's/\(\[\|\]\)//g'

ou isto:

echo '[123]' | sed -r 's/(\[|\])//g'

Você também pode tentar uma abordagem diferente e corresponder à string dentro dos colchetes (supondo que a string possa corresponder facilmente e não seja definida pelos colchetes):

echo '[123]' | egrep -o "[0-9]+"

Estou tendo os mesmos problemas com o seu regex original usando, grepentão desconfio que isso não seja apenas uma sedcoisa.

Estranhamente, eles produzem resultados diferentes, mas um deles corresponde ao que você deseja:

echo '[123]' | egrep -o '[^][]+'
123

echo '[123]' | egrep -o '[^[]]+'
3]

Aplicando isso ao seu original sed(e adicionando o /gmodificador para remover os dois colchetes):

echo '[123]' | sed 's/[][]//g'
123

Sua terceira abordagem (egrep -o ...) parece a solução mais limpa para o meu problema. Eu só terei números inteiros entre colchetes (e desculpe, eu deveria ter mencionado isso na minha pergunta), então não devo encontrar nenhuma esquisitice. Obrigado!
Xhantar 11/01

3
Você também pode usar tr: echo '[123]' | tr -d '[]'- evita confusões de expressões regulares sobre como escapar.
James O'Gorman

@ James O'Gorman - Interessante. Por alguma razão, pensei que isso trpudesse traduzir apenas um caractere no máximo por vez, mas eu estava errado. Obrigado!
Xhantar 11/01

4

Para remover tudo antes e depois dos colchetes:

$ echo '[123]' | sed 's/.*\[//;s/\].*//;'
123

Se seus dados forem assim, sempre significa começar e terminar com colchetes:

$ echo '[123]' | sed 's/.//;s/.$//;'
123

Os dados com os quais estou trabalhando sempre começam e terminam com um colchete sim. Ainda gostaria de saber por que minha solução não estava funcionando. Alguma ideia? E existe uma maneira de fazer isso sem especificar 2x regex?
Xhantar

1
@Guru, esta solução funcionou comigo e, quanto ao Xhantar, esta é uma resposta muito tardia, mas o que posso ver no seu código e no guia Bash Beginners em tldp.org, você estava tentando fazer várias pesquisas e substituir, uma para '[' e o outro para ']' que não funcionam, para espaçar duas pesquisas diferentes e substituir, use o ";" ou as opções -e. 's / <search> / <replace> / g; s / <search> / <replace> / g 'OU sed -e' s / <search> / <replace> / g '-e' s / <search> / <replace> / g '
ArunMKumar

1

Se você possui uma string mais complexa como 'abcdef [123] ghijk', também pode usar o comando bash interno 'cut' para extrair texto apenas entre colchetes:

$ echo 'abcdef[123]ghijk' | cut -d '[' -f 2 | cut -d ']' -f 1
123

1

Você pode escapar do suporte de abertura usando \[. Para o suporte de fechamento, use []].

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.