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
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
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'
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
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
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