2016-04-05 12 views
-4

zu ändern Ich brauche einen sed-Befehl, um ein Telefonnummernformat von 999-999-9999 zu (999)999-9999 zu ändern. Hier ist, was ich habe versucht:Ich brauche einen sed-Befehl, um ein Telefonnummernformat von 999-999-9999 in (999)999-9999

sed 's/[[:digit:]]\-[[:digit:]]\-[[:digit:]]/\([[:digit:]]\)[[:digit:]]\-[[:digit:]]/gp' 

Ich habe auch versucht, dies:

sed 's/([0-9]{3})\-([0-9]{3})\-([0-9]{4})/\(([0-9]{3}\))([0-9]{3})\-([0-9]{4})/gp' 
+0

Die Einheiten '[[: digit:]]' entsprechen einer einzelnen Ziffer, nicht dreistellig. –

Antwort

2

Die Notation [[:digit:]] eine einzelne Ziffer übereinstimmt; Sie müssen die Anzahl der wiederholten Stellen abgleichen, indem Sie die Wiederholungszahl in \{3\} einschließen (für eine feste Anzahl; es gibt auch variable gezählte Bereiche, aber sie sind hier nicht relevant, und * und so weiter). Und Sie müssen erfassen, was Sie in \(…\) übereinstimmen, damit Sie sie im Ersatz referenzieren können. Bei der Ersetzung verwenden Sie \1 usw., um auf erfasste Fragmente zu verweisen. Die Aufnahmen sind von links nach rechts in der Reihenfolge der \( Symbole nummeriert.

sed 's/\([[:digit:]]\{3\}\)-\([[:digit:]]\{3\}-[[:digit:]]\{4\}\)/(\1)\2/g' 

Oder:

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

Das ist eine klassische sed Notation; Sie können Varianten auch mit erweiterten regulären Ausdrücken finden, aber Sie benötigen unterschiedliche Optionen, abhängig von der Plattform, im Gegensatz zu dieser Notation. Die Muster suchen nach 3 Ziffern (erste Erfassung), einem Bindestrich, dann 3 weiteren Ziffern, einem weiteren Gedankenstrich und 4 Ziffern als zweite Erfassung und ersetzen all dies durch offene Klammer (Klammer in Amerikanisch), die ersten 3 Ziffern, Klammer schließen, und die restlichen 3 Ziffern, Strich, 4 Ziffern.

BSD (Mac OS X):

sed -E 's/([0-9]{3})-([0-9]{3}-[0-9]{4})/(\1)\2/g' 

GNU:

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

Beachten Sie, dass alle diese regulären Ausdrücke

9876-345-54321 

umwandeln würde:

9(876)345-54321 

Befestigung, die weniger trivial ist, besonders in sed. Mit Perl:

$ echo "987-654-3210 and 2987-654-and 222-333-4444 and 543-432-5544" | 
> perl -p -e 's/\b([0-9]{3})-([0-9]{3}-[0-9]{4})\b/(\1)\2/g' 
(987)654-3210 and 2987-654-and (222)333-4444 and (543)432-5544 
$ 

Die \b Mark Wortgrenze in PCRE. Das bedeutet, dass a222-333-4444 nicht von der Perl übereinstimmt; Sie können Dinge verfeinern, um auf Nicht-Ziffern oder den Beginn von Strings davor und auf Nicht-Ziffern oder das Ende von Strings nach dem passenden String zu bestehen.

$ echo "987-654-3210 and 2987-654-and a222-333-4444 and 543-432-5544" | 
> perl -p -e 's/(^|\D)([0-9]{3})-([0-9]{3}-[0-9]{4})(\D|$)/\1(\2)\3\4/g' 
(987)654-3210 and 2987-654-and a(222)333-4444 and (543)432-5544 
$ 

Oder mit (BSD oder GNU) sed erweiterte reguläre Ausdrücke (BSD dargestellt):

$ echo "987-654-3210 and 2987-654-and a222-333-4444 and 543-432-5544" | 
> sed -E 's/(^|[^0-9])([0-9]{3})-([0-9]{3}-[0-9]{4})([^0-9]|$)/\1(\2)\3\4/g' 
(987)654-3210 and 2987-654-and a(222)333-4444 and (543)432-5544 
$ 

Beachten Sie, dass das negierte stelligen Zeichenklasse Notation [^[:digit:]] geschrieben werden können, wenn Sie es wünschen.

Iterative Entwicklung hilft.

+0

Super, danke !! Kannst du erklären, was genau dieser Teil macht, (\ 1) \ 2 /? – Edwin

+0

In der ersten Variante fängt '\ (... \)' 'einen Teil von dem ein, was gefunden wurde. Bei der Ersetzung können Sie so oft wie nötig auf die erfassten Fragmente verweisen (hier jeweils einmal), indem Sie '\ 1' usw. verwenden, um auf die Fragmente zu verweisen. Die Fragmente werden durch die Sequenz indiziert, in der die Symbole \ erscheinen. So ersetzt das '(\ 1) \ 2' die Ziffer-Strich-Zeichenfolge durch eine offene Klammer, die erste dreistellige Gruppe, eine enge Klammer und die zweite aufgenommene Saite (999-9999) –

+0

Danke für die Hilfe! – Edwin

1
$ echo 123-456-7890 | sed -r 's/([0-9]{3})-([0-9]{3}-[0-9]{4})/(\1)\2/' 
(123)456-7890 
+1

Warum nicht 'awk' verwenden? – hek2mgl

+0

@ hek2mgl: Weil die Frage nach 'sed' (nach dem Tag und nach dem, was ausprobiert wurde) gefragt wird. Ich sehe "awk" nicht als einen großen Vorteil hier; die Verwendung von 'gsub' oder gleichwertig ist möglich, aber wenn überhaupt, ist die Notation unhandlicher als' sed'. –

+0

Ich denke, es war ein Witz. – karakfa

Verwandte Themen