using sed command to replace first 2 occurrences of “:” within a string

5,704

Solution 1

[Answering the question as asked - although it's likely not the best way to approach your actual date comparison problem]

One way would be to replace colons one at a time using a loop, breaking out of the loop when the result contains two hyphens:

echo '2018:01:16 12:25:35' | sed ':a; /^[^-]*-[^-]*-/ b; s/:/-/; ta'
2018-01-16 12:25:35

Alternatively, if you have GNU sed, you could replace all the colons with hyphens, then replace from the third hyphen onward with colons again:

echo '2018:01:16 12:25:35' | sed 'y/:/-/; s/-/:/3g'
2018-01-16 12:25:35

Solution 2

Just do a simple substitution twice:

sed 's/:/-/;s/:/-/'

Solution 3

I have used below 2 methods to achieve the mentioned result

method1 using awk gsub function

echo $date1| awk '{gsub(":","-",$1);print $0}'

output 2018-01-16 12:25:35

Method2 using sed

echo $date1 |sed "s/:/-/"| sed "s/:/-/"

output 2018-01-16 12:25:35

Method3 using perl

echo $date1| perl -pne "s/:/-/"| perl -pne "s/:/-/"

output 2018-01-16 12:25:35

Solution 4

| sed 's/\([0-9]*\).*/\1/'

This saves the first string of digits, eats everything after that with the .* then puts those digits back, so indeed anything after the 2018 disappears.

You'd need to capture the first two strings of digits, plus the separators to replace them, and not match the rest of the line:

$ echo "2018:01:16 12:25:35" | sed 's/\(....\):\(..\):/\1-\2-/'
2018-01-16 12:25:35

Solution 5

Consider using the GNU date command directly:

date1=$(date +”%Y-%m-%d %H-%M-%S”)
Share:
5,704

Related videos on Youtube

Fxbaez
Author by

Fxbaez

Updated on September 18, 2022

Comments

  • Fxbaez
    Fxbaez over 1 year

    I am trying to compare 2 dates in the format YYYY:MM:DD HH:MM:SS by using the date (bash) command. My problem is that the date command only uses the date format (as far as I know) YYYY-MM-DD HH:MM:SS. I was trying to use sed with regular expressions to replace the first 2 occurrences of : with - but I was not able to get it to work. I’m only getting 2018.

    date1="2018:01:16 12:25:35"
    echo $date1 | sed 's/\([0-9]*\).*/\1/'
    

    I’ll take any possible suggestions and thank you.

    • Guy
      Guy over 6 years
      How do you want to compare them? Put them in date order, or after a particular date or..? As Jeff shows below, you can change the date commands output format. gnu.org/software/coreutils/manual/html_node/…
    • Fxbaez
      Fxbaez over 6 years
      I have an array that will store the dates and a couple of loops will sort them but the issue is that in order for me to sort them I need to compare them and I need for them to be in the format mentioned in the question.
    • Guy
      Guy over 6 years
      I think it would be sed -E ‘s/([[:digit:]]{4}):([[:digit:]]{2}):([[:digit:]]{2})(.*)/\1‌​-\2-\3\4/‘ maybe. Capture year, month, day, and rest, and reprint.
    • Guy
      Guy over 6 years
      Oh, and the problem with your regret is your are only capturing up to the first colon, as you character class is just numbers, and you don’t hen capture the following groups.
    • smw
      smw over 6 years
      With GNU sed you could replace all of the colons - then swap back from the third onward e.g. 's/:/-/g; s/-/:/3g'
    • Alessio
      Alessio over 6 years
      you should fix the problem at the source if you can - i.e. fix whatever it is that's producing dates in that bogus format. Nobody uses : as separator between year, month, day.
  • Fxbaez
    Fxbaez over 6 years
    Im trying to change the format as you suggested and storing it in a new variable called date2 by typing this command. date2=$(date - - date=“$date1” +”%Y-%M-%D %H:%M:%S”) and I get invalid date ... any additional suggestions?
  • Fxbaez
    Fxbaez over 6 years
    Your proposed solution generates the date with the format based on the current date not the date that I would like to specify.
  • John1024
    John1024 over 6 years
    @Fxbaez In Unix commands, spaces count. Remove the spaces from - - date.
  • Fxbaez
    Fxbaez over 6 years
    Lets say that I have 2 dates with my original format YYYY:MM:DD HH:MM:SS .. how would you suggest that I compare the 2 dates?
  • Guy
    Guy over 6 years
    @Fxbaez you can use test and [[ ... ]] in the shell to check ordering, or even just use sort depending on what you actually need to do.
  • Alessio
    Alessio over 6 years
    GNU date can't parse a date with : separating Y,M,D. date: invalid date '2018:01:16 12:25:35'. that's the point of this question.
  • potong
    potong almost 3 years
    s/:/-/g can be replaced by y/:/-/
  • smw
    smw almost 3 years
    @potong good point - let's give the y command some love...