Usando sed para eliminar un corchete de apertura y cierre alrededor de una cuerda

18

Estoy ejecutando este comando en un shell bash en Ubuntu 12.04.1 LTS. Estoy tratando de eliminar los caracteres [y ]de una sola vez, es decir, sin tener que hacer una tubería para sed por segunda vez.

Sé que los corchetes tienen un significado especial en una expresión regular, así que me estoy escapando de ellos al anteponer una barra invertida. ¡El resultado que esperaba era solo la cadena, 123pero los corchetes permanecen y me encantaría saber por qué!

~$ echo '[123]' | sed 's/[\[\]]//'
[123]
Xhantar
fuente
Lo que estoy tratando de lograr en última instancia es asignar lo que esté entre corchetes a una variable bash para usarlo en otra parte de mi script bash, así que si hay una mejor manera de lograrlo (¿usando awk, tal vez?), Hágamelo saber .
Xhantar
2
Solo agregando como comentario: puede usar la función PE de bash como en: str='[123]'; str1=${str/\[/}; str2=${str1/\]}; echo $str2
Valentin Bajrami
1
@ val0x00ff - Pura sustitución de bash .. ¡gracias! :) Aprendí algo nuevo.
Xhantar

Respuestas:

24

Esto es fácil si sigue el manual cuidadosamente: todos los miembros dentro de una clase de personaje pierden un significado especial (con algunas excepciones). Y] pierde su significado especial si se coloca primero en la lista. Tratar:

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

Esto dice:

  1. dentro de los [corchetes] externos , reemplace cualquiera de los caracteres incluidos, a saber:
    • ] y
    • [
  2. reemplazar cualquiera de ellos por la cadena vacía, de ahí la cadena de reemplazo vacía //,
  3. reemplazarlos en todas partes ( globalmente ), de ahí la final g.

Nuevamente, ] debe ser el primero en la clase siempre que esté incluido.

Saparagus
fuente
11

No estoy seguro de por qué eso no funciona, pero esto sí:

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

o esto:

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

También puede intentar un enfoque diferente y hacer coincidir la cadena dentro de los corchetes (suponiendo que la cadena se pueda combinar fácilmente y no se define por los corchetes):

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

Tengo los mismos problemas con su expresión regular original, grepasí que sospecho que esto no es solo una sedcosa.

Extrañamente, estos producen resultados diferentes, pero uno de ellos coincide con lo que quieres:

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

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

Aplicando esto a su original sed(y agregando el /gmodificador para que elimine ambos corchetes):

echo '[123]' | sed 's/[][]//g'
123
Ladadadada
fuente
Su tercer enfoque (egrep -o ...) parece la solución más limpia para mi problema. Solo tendré enteros entre corchetes (y lo siento, debería haber mencionado eso en mi pregunta), así que no debería encontrar ninguna rareza, creo. ¡Gracias!
Xhantar
3
También puede usar tr: echo '[123]' | tr -d '[]'- evita las confusiones de expresiones regulares acerca de escapar.
James O'Gorman el
@James O'Gorman - Interesante. Por alguna razón, pensé que trsolo podía traducir un carácter máximo a la vez, pero estaba equivocado. ¡Gracias!
Xhantar
4

Para eliminar todo antes y después de los corchetes:

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

Si sus datos son así, siempre significa comenzar y terminar entre corchetes:

$ echo '[123]' | sed 's/.//;s/.$//;'
123
Gurú
fuente
Los datos con los que estoy trabajando siempre comenzarán y terminarán con un corchete sí. Sin embargo, todavía me gustaría saber por qué mi solución no funcionaba. ¿Algunas ideas? ¿Y hay alguna manera de hacer esto sin especificar 2x expresiones regulares?
Xhantar
1
@Guru esta solución funcionó por mí, y en cuanto a Xhantar, esta es una respuesta muy tardía, pero lo que puedo ver en su código y en la guía Bash Beginners en tldp.org, estaba tratando de hacer búsquedas múltiples y reemplazar, una para '[' y el otro para ']' que no funcionará, para espaciar dos búsquedas diferentes y reemplazar use el ";" o las opciones -e. 's / <search> / <replace> / g; s / <search> / <replace> / g 'OR sed -e' s / <search> / <replace> / g '-e' s / <search> / <replace> / g '
ArunMKumar
1

Si tiene una cadena más compleja como 'abcdef [123] ghijk', también puede usar el comando bash interno 'cut' para extraer texto solo entre corchetes:

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

Puede escapar del soporte de apertura usando \[. Para el soporte de cierre, use []].

usuario2428118
fuente