Como remover certos caracteres (mas não todos) antes de um ou mais caractere (s)?

3

Se eu quisesse remover tudo antes de um caractere (digamos "("), eu faria algo assim 's/.*(//g' . Agora eu quero remover apenas certas coisas antes de um caractere / alguns caracteres, no meu caso - e antes de ( (incluindo espaço)

Eu tentei algumas coisas, mas nenhuma funcionou. Um exemplo é:

sed 's/ *(/(/g'

Mas isso só removeu o espaço antes e não os outros, o que faz sentido para mim ao ler o código (ele vai remover tudo entre o espaço e ( , mas tive que tentar algo antes de perguntar aqui), então tentei isso: (que também não funcionou)

sed 's/* (/(/g'

Mas desta vez não vejo por que não. Eu pensei que era porque espaços são personagens muito especiais, então eu tentei com - ( s/*- (/(/g' e s/*-* (/(/g' ), mas eles não funcionaram também.

Entrada:

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

Saída desejada:

0813796249 (Hems)
    
por DisplayName 03.12.2015 / 01:45

2 respostas

2

Você deseja remover todos os espaços e traços imediatamente antes de ( ? Então você precisa usar uma classe de caractere ou "expressão de colchetes", incluindo espaço e traço: [- ]

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

Veja man 7 regex e procure bracket expression para mais detalhes.

Com a entrada que você mencionou ( 081 379 62 49 (Hems) ou 081-379-62-49 (Hems) ), você pode fazer isso com awk :

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

isso diz ao awk para usar ( como separador de campo e, em seguida, usa a função gsub() para remover espaços e traços do primeiro campo (o número de telefone). O Output Field Separator (OFS) é definido como ( (espaço e ( ) para produzir a saída correta.

por exemplo,

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

BTW, se não houver espaços ou traços após o número de telefone (por exemplo, dentro do (...) ), você também pode fazer isso com o sed:

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

Isso remove TODOS os espaços e traços da linha de entrada e, em seguida, coloca um espaço de volta imediatamente antes do ( . Isso irá desagradar a saída horrivelmente se houver várias palavras dentro dos parênteses (campo comment / name?)

Provavelmente, existe uma maneira complicada de fazer isso corretamente, copiando o número do telefone para manter o espaço, modificando-o e reinserindo-o novamente na linha de saída, mas é muito mais fácil fazer isso com o awk.

    
por 03.12.2015 / 02:19
1

isso funciona com sed :

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

O truque é deixar sed remover uma string nula quando não estiver removendo uma das strings que você deseja. Dessa forma, a substituição g lobal pode abranger todo o espaço do padrão removendo um monte de nada - ( \{0,1\} - 0 ou 1 ocorrências) - até que acenda em algum caractere alvo e o substitua , ou o substitui por si mesmo - como fará com qualquer caractere que ocorra entre um par de () .

    
por 03.12.2015 / 04:20