¿Cómo eliminar ciertos caracteres (pero no todos) antes de uno o más caracteres?

Si quisiera eliminar todo antes de un personaje (digamos "("), simplemente haría algo como esto 's/.*(//g' . Ahora quiero eliminar solo ciertas cosas antes de un personaje / algunos personajes, en mi caso - y antes ( (incluido el espacio)

Intenté algunas cosas pero ninguna funcionó. Un ejemplo es:

 sed 's/ *(/(/g' 

Pero esto solo eliminó el espacio anterior y no los demás, lo que tiene sentido para mí al leer el código (eliminará todo entre el espacio y ( , pero tuve que probar algo antes de preguntar aquí), así que probé esto: (que tampoco funcionó)

 sed 's/* (/(/g' 

Pero esta vez no puedo ver por qué no. Pensé que era porque los espacios son personajes muy especiales, así que probé con - lugar ( s/*- (/(/g' y s/*-* (/(/g' ) pero tampoco funcionaron.

Entrada:

 081 379 62 49 (Hems) 081-379-62-49 (Hems) 

Salida deseada:

 0813796249 (Hems) 

Desea eliminar todos los espacios y guiones inmediatamente antes ( ? Entonces debe usar una class de caracteres o "expresión de paréntesis" que incluya espacio y guión: [- ]

 sed -e 's/[- ]*(/(/g' 

Vea man 7 regex y busque la bracket expression para más detalles.

Con la información que mencionaste ( 081 379 62 49 (Hems) o 081-379-62-49 (Hems) ), puedes hacerlo con awk :

 awk -F'(' 'BEGIN {OFS=" ("} ; {gsub(/[- ]/,"",$1) ; print}' 

esto le dice a awk que use ( como separador de campo, y luego usa la function gsub() para eliminar espacios y guiones del primer campo (el número de teléfono). El Separador de campos de salida (OFS) está establecido en ( (espacio y ( ) en para producir la salida correcta

p.ej

 echo -e "081 379 62 49 (Hems)\n081-379-62-49 (Hems)" | awk -F'(' 'BEGIN {OFS=" ("} ; {gsub(/[- ]/,"",$1) ; print}' 0813796249 (Hems) 0813796249 (Hems) 

Por cierto, si no hay espacios o guiones después del número de teléfono (por ejemplo, dentro del (...) ) también podría hacer esto con sed:

 echo -e "081 379 62 49 (Hems)\n081-379-62-49 (Hems)" | sed -e 's/[ -]//g ; s/(/ (/' 

Esto elimina TODOS los espacios y guiones de la línea de input, y luego devuelve un espacio inmediatamente antes de que ( . Uglify la salida horrendo si hay varias palabras dentro de los paréntesis (campo de comentario / nombre?)

Probablemente exista alguna forma barrocamente complicada de hacerlo correctamente al copyr el número de teléfono para mantener el espacio y modificarlo allí y luego volverlo a insert en la línea de salida, pero es mucho más fácil hacerlo con awk.

esto funciona con sed :

 printf %s\\n '081 379 62 49 (Hems)' \ '081-379-62-49 (Hems)' | sed 's/\( ([^)]*)\)\{0,1\}[ -]\{0,1\}/\1/g' 

 0813796249 (Hems) 0813796249 (Hems) 

El truco es dejar que sed elimine una cadena nula cuando no está eliminando una de las cadenas que desea. De esta forma, la sustitución global puede abarcar todo el espacio del patrón eliminando un montón de nada – ( \{0,1\} – 0 o 1 ocurrencias) – hasta que enciende un personaje específico y lo sustituye, o lo reemplaza con en sí mismo, como lo hará con cualquier carácter que ocurra entre un par de () .