Question

I have to change a CSV file column (the date) which is written in the following format:

YYYY-MM-DD

and I would like it to be

YYYY.MM.DD

I can write a succession of 2 sed rules piped one to the other like :

sed 's/-/./' file.csv | sed 's/-/./' 

but this is not clean. my question is: is there a way of assigning variables in sed and tell it that YYYY-MM-DD should be parsed as year=YYYY ; month=MM ; day=DD and then tell it

write $year.$month.$day

or something similar? Maybe with awk?

Was it helpful?

Solution

You could use groups and access the year, month, and day directly via backreferences:

sed 's#\([0-9][0-9][0-9][0-9]\)-\([0-9][0-9]\)-\([0-9][0-9]\)#\1.\2.\3#g'

OTHER TIPS

Here's an alternative solution with awk:

awk 'BEGIN { FS=OFS="," } { gsub("-", ".", $1); print }' file.csv
  • BEGIN { FS=OFS="," } tells awk to break the input lines into fields by , (variable FS, the [input] Field Separator), as well as to also use , when outputting modified input lines (variable OFS, the Output Field Separator).
  • gsub("-", ".", $1) replaces all - instances with . in field 1
    • The assumption is that the data is in the 1st field, $1; if the field index is a different one, replace the 1 in $1 accordingly.
  • print simply outputs the modified input line, terminated with a newline.

What you are doing is equivalent to supplying the "global" replacement flag:

sed 's/-/./g' file.csv

sed has no variables, but it does have numbered groups:

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

or, if your sed has no -r:

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

You may try this sed command also,

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

Example:

$ (echo '2056-05-15'; echo '2086-12-15'; echo 'foo-bar-go') | sed 's/\([0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\)/\1.\2.\3/g'
2056.05.15
2086.12.15
foo-bar-go
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top