0

I have a file with dates like 01/01/2022 in a file that I need to change to 01-01-2022. I need to use the sed command to change the format (for a homework assignment).

So far I have tried:

s|([0-9]{2})/([0-9]{2})/([0-9]{4})|\3-\2-\1| file name sed -e 's/([0-9][0-9]/])/([0-9][0-9]/)/\([0-9][0-9][0-9][0-9]/)/\1-2-3\g' file name sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)$/\1-\2-\3/' filename 

None have worked for me. I'm not sure what else to try, any suggestions would be appreciated!

thanks!

3
  • Take one example line out of the file, paste in into a regex tester website (there are many to choose from), select sed-compatible regular expressions, and edit your regex with instant feedback until it works. Then try it at the command-line, on the whole file. Commented Sep 30, 2022 at 20:09
  • Why are you reversing the order in the 1st and last attempts? Commented Sep 30, 2022 at 20:11
  • Probably your sed doesn't understand {2} repetition. The longhand attempt failed because you forgot to backslash the parentheses and had other syntax errors. s|\([0-9][0-9]\)/\([0-9][0-9]\)/\([0-9][0-9][0-9][0-9]\)|\3-\2-\1| should work with the most pedestrian seds. Commented Sep 30, 2022 at 20:17

3 Answers 3

1

You are almost there …

This must be run as extended regex (sed -r or sed -E) and it outputs year-day-month:

s|([0-9]{2})/([0-9]{2})/([0-9]{4})|\3-\2-\1| filename # ^^^^^^^^-- likely want \1-\2-\3 

The next has a stray closing bracket in the expression and could benefit from a different separator for the s command. Using | like in your first version avoids having to escape all slashes, which you are not doing. It's confusing forward slashes and backslashes too and must either escape all parentheses or use -E/-r and not escape any parentheses:

sed -e 's/([0-9][0-9]/])/([0-9][0-9]/)/\([0-9][0-9][0-9][0-9]/)/\1-2-3\g' filename # || | | | | |||^-- must be a forward slash, not a backslash # || | | | | ^^^-- must be \2-\3 # || ^-----------(-+-- must be escaped (or use a different separator) # ^^--- stray closing bracket | # ^------------------------+-- should be backslashes or removed (depending on whether using basic or extended regex) 

And the last one should work, but only matches dates at the end of the line

sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)$/\1-\2-\3/' filename # ^-- matches only at end of line 
Sign up to request clarification or add additional context in comments.

Comments

1
$ echo '01/01/2022'|sed 's@/@-@g' 01-01-2022 

And the case where other slashes are preserved:

$ echo 'abc/d 01/01/2022'|sed -E 's/([0-9]+)\/([0-9]+)\/([0-9]+)/\1-\2\-\3/' abc/d 01-01-2022 

1 Comment

OP seems to be making an effort to only replace the slashes found in dates, leaving any other slashes intact.
0

You need the -r option for () and {} to work without escaping them. Then the first method works if you use \1-\2-\3 as the replacement.

$ sed -r 's|([0-9]{2})/([0-9]{2})/([0-9]{4})|\1-\2-\3|' <<EOF foo 01/22/3456 bar EOF foo 01-22-3456 bar 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.