Reputation: 21
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
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
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:
\
-escaping ( ) { }
char.\<
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
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