Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I need to format phone numbers in a text file. They appear as (example) 8014516912

How would I format it so that I can insert a - after the first 3 numbers, and then another - after another 3 numbers, so it would appear as 801-451-6912

How would I do this for all lines that contain a phone number? Keep in mind that the phone numbers are between text, so the numbers aren't always at the same index. For example it can be like:

atewfnwieug 8204919561
adw 8915617141
share|improve this question
add comment

2 Answers

I would use perl for this instead:

$ perl -pe 's/\b(\d{3})(\d{3})(\d{4})\b/$1-$2-$3/' foo.txt 
atewfnwieug 820-491-9561

adw 891-561-7141 

You can also do it in place, sed-like:

$ perl -i.bak -pe 's/\b(\d{3})(\d{3})(\d{4})/$1-$2-$3\b/' foo.txt 

If your phone numbers can be adjacent to letters like this:

abcd1234567890abc
abcd1234567890
1234567890abc

you can use this one instead:

$ perl -pe 's/([^\d]*)(\d{3})(\d{3})(\d{4})([^\d]*)/$1$2-$3-$4$5/' foo.txt 
abcd123-456-7890abc
abcd123-456-7890
123-456-7890abc

All these choices assume that phone numbers are always 10 digits long as in your example.

share|improve this answer
    
You might want to anchor the pattern so as not to perform the substitution on numerical strings longer than 10 digits. –  Joseph R. Oct 14 '13 at 0:56
    
@JosephR. good point, answer edited, thanks. –  terdon Oct 14 '13 at 1:02
add comment

You need numerical quantifiers for this:

sed -r 's/\b([0-9]{3})([0-9]{3})([0-9]{4})\b/\1-\2-\3/' your_file

The -r switch, which enables extended regular expressions, is not POSIX though, so a more portable solution would be

perl -pe 's/\b([0-9]{3})([0-9]{3})([0-9]{4})\b/$1-$2-$3/' your_file

In extended regular expressions, the quantifier {n,m} means match the previous atom at least n times and at most m times. For example, the quantifier ? can be expressed as {0,1}. Omitting m means no upper limit: + can be written as {1,}. Finally, {n} means match the previous atom exactly n times.

If you want to use sed, you don't exactly need to have extended regular expressions for this; it's just that the basic regular expressions form would be less readable:

sed 's/\b\([0-9]\{3\}\)\([0-9]\{3\}\)\([0-9]\{4\}\)\b/\1-\2-\3/' your_file
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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