If I wanted to remove everything before a character (say "("), I would just do something like this 's/.*(//g'. Now I want to remove only certain things before a character/some characters, in my case - and before ( (including space)

I tried a few things but none worked. One example is:

sed 's/ *(/(/g'

But this only removed the space before and not the others, which makes sense to me when reading the code (it will remove everything between the space and (, but I had to try something before asking here), so I tried this: (which also didn't work)

sed 's/* (/(/g'

But this time I can't see why not. I thought it was because spaces are pretty special characters so I tried with - instead (s/*- (/(/g' and s/*-* (/(/g') but they didn't work either.


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

Desired output:

0813796249 (Hems)
  • Please define "didn't work", including any error messages you may have been given. – roaima Dec 3 '15 at 1:31
  • 1
    Show your input and your desired output. – glenn jackman Dec 3 '15 at 1:36
  • @roaima, if there were any error messages I would have said them. Sorry for just assuming, but I thought people would understand I meant that file/words didn't change as I like. – DisplayName Dec 3 '15 at 2:03
  • @glennjackman inputs are either 081 379 62 49 (Hems) or 081-379-62-49 (Hems) and output is 0813796249 (Hems) – DisplayName Dec 3 '15 at 2:09

You want to remove all spaces and dashes immediately before (? Then you need to use a character class or "bracket expression" including space and dash: [- ]

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

See man 7 regex and search for bracket expression for more details.

With the input you mentioned (081 379 62 49 (Hems) or 081-379-62-49 (Hems)), you can do it with awk:

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

this tells awk to use ( as field separator, and then uses the gsub() function to remove spaces and dashes from the first field (the phone number). The Output Field Separator (OFS) is set to ( (space and () in order to produce the correct output.


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

BTW if there are no spaces or dashes after the phone number (e.g. inside the (...)) you could also do this with sed:

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

This strips ALL spaces and dashes from the input line, and then puts one space back immediately before the (. It will uglify the output horrendously if there are multiple words inside the parentheses (comment/name field?)

There's probably some baroquely complicated way of doing it properly in sed by copying the phone number to hold space and modifying it there and then re-inserting it back into the output line, but it's much easier to do it wth awk.

  • Not immediately before, but I also meant ` (` . A space before (. – DisplayName Dec 3 '15 at 2:06
  • if you don't mean immediately before, then what do you mean? you need to be much clearer in expressing your goal. – cas Dec 3 '15 at 2:09
  • This might be a language issue, because I don't speak English natively, but exactly what do you mean with "immediately before"? I thought you meant everything before ( but "everything" stops when there's a space. – DisplayName Dec 3 '15 at 2:14
  • Thanks. I really need to learn awk, it seems to be more efficient than sed. – DisplayName Dec 3 '15 at 2:19
  • sed is often a lot faster and simpler to use than awk but has its limitations....and that's where awk or perl should be used. – cas Dec 3 '15 at 2:22

this works with 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)

The trick is to let sed remove a null string when it isn't removing one of the strings you want it to. In that way the global substitution can span the entire pattern space removing a bunch of nothing - (\{0,1\} - 0 or 1 occurrences) - until it lights on some targeted character and substitutes it away, or replaces it with itself - as it will do for any characters occurring between a pair of ().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.