Horia Dragomir
Horia Dragomir

Reputation: 21

Replace the separator between pairs of numbers

I want to replace all strings like [0-9][0-9]-[0-9][0-9] with [0-9][0-9]/[0-9][0-9] using sed.

In other words, I want to replace - with /.

If I have somewhere in my text:

09-36
32-43
54-65

I want this change:

09/36
32/43
54/65

Upvotes: 0

Views: 65

Answers (3)

Ruslan Osmanov
Ruslan Osmanov

Reputation: 21492

perl -C -npe 's/(?<!\d)(\d\d)-(\d\d)(?!\d)/\1\/\2/g' file

Input

维基 1-11 22-33 444-44 55-555 66-66百科
77-77
8 88-88

Output

维基 1-11 22/33 444-44 55-555 66/66百科
77/77
8 88/88

In the command above

  • -C enables Unicode;
  • -n causes Perl to process the script for each input line;
  • -p causes Perl to print the result of the script to the standard output;
  • -e accepts a Perl expression (particularly, it is a substitution).

In this mode (-npe), Perl works just like sed. The script substitutes each pair of digits separated with - to the same pair separated with a slash.

(?<!\d) and (?!\d) are negative lookaround expressions.


To edit the file in place use -i option: perl -C -i.backup -npe ....


If the input is not a file, you can pass the input to Perl via pipe, e.g.:

echo '维基 1-11 22-33 444-44 55-555 66-66百科' | \
  perl -C -npe 's/(?<!\d)(\d\d)-(\d\d)(?!\d)/\1\/\2/g'

Upvotes: 1

mklement0
mklement0

Reputation: 437688

Using GNU sed:

$ echo '09-36 32-43 54-65' | sed -r 's|\<([0-9]{2})-([0-9]{2})\>|\1/\2|g'
09/36 32/43 54/65
  • -r turns on extended regular expressions, which:

    • doesn't require \-escaping ( ) { } char.
    • enables use of \< and /> to only match at word boundaries (if the expression should only match full lines, use ^ and $ instead, and omit the g option)
  • | is used as an alternative regex delimiter so that / can be used without \-escaping.

A BSD/macOS sed solution would look slightly different:
echo '09-36 32-43 54-65' | sed -E 's|[[:<:]]([0-9]{2})-([0-9]{2})[[:>:]]|\1/\2|g'

Upvotes: 3

Benjamin Podszun
Benjamin Podszun

Reputation: 9827

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

Might not be the most elegant version, but works for me. The gazillion backslashes make this rather unreadable in my opinion. You might improve the readability by not using / to separate the pattern and the replacement maybe?

Upvotes: 1

Related Questions