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 optional0
and then any one digit, or1
and a0
or1
after it (10
and11
)(?=:[0-5]?\d\s*PM)
- a positive lookahead that requires:
, an optional digit from0
to5
and then any one digit, zero or more whitespaces andPM
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