Home > other >  Replace only the beginning of a line
Replace only the beginning of a line

Time:04-07

I am struggling with a sed command. I am trying to achieve this:

Input: 03:23PM

Output: 15:23PM

My sed command which I have tried:

echo $line | sed 's/03:..PM/15:..PM/g

CodePudding user response:

To remember part of the replacement test, use parentheses. To refer to the first pair of parentheses, use \1:

sed 's/03:\(..\)PM/15:\1PM/g'

In fact, you can make both the : and PM part of the capture group:

sed 's/03\(:..PM\)/15\1/g'

CodePudding user response:

I would use awk so you are getting actual addition and can detect AM vs PM:

echo '03:23PM
11:33PM
03:23AM' | awk 'BEGIN{FS=OFS=":"} /PM/ && $1<12 {$1=$1 12} 1'

Prints:

15:23PM
23:33PM
03:23AM

CodePudding user response:

Using sed

$ sed '/[0-9:]*[AP]M/s/^[^:]*/15/' <<< $line
15:23PM

Or using @dawg solution to handle multiple ranges

sed "/PM/s/^[^:]*/echo \$((& 12))/e" <<< $line
15:23PM

CodePudding user response:

In case you need to handle this task in any kind of context, and taking into consideration that you only need to tackle 00-11 hours, you can use Perl:

perl -pe 's/(?<!\d)(0?\d|1[01])(?=:[0-5]?\d\s*PM)/$1 12/ge' file

See the regex demo. Details:

  • (?<!\d) - no digit immediately on the left is allowed
  • (0?\d|1[01]) - Group 1 ($1): an optional 0 and then any one digit, or 1 and a 0 or 1 after it (10 and 11)
  • (?=:[0-5]?\d\s*PM) - a positive lookahead that requires :, an optional digit from 0 to 5 and then any one digit, zero or more whitespaces and PM substring immediately to the right of the current location.

The $1 12 replacement is an expression that sums the found hour value with 12.

See the online demo:

#!/bin/bash
text='Time: 00:23PM
Time: 03:23PM
Time: 11:23PM

Time: 12:23PM
Time: 13:45PM'
perl -pe 's/(?<!\d)(0?\d|1[01])(?=:[0-5]?\d\s*PM)/$1 12/ge' <<< "$text"

Output:

Time: 12:23PM
Time: 15:23PM
Time: 23:23PM

Time: 12:23PM
Time: 13:45PM
  • Related