Чтобы запомнить часть замещающего теста, используйте круглые скобки. Чтобы обратиться к первой паре скобок, используйте \1
:
sed 's/03:\(..\)PM/15:\1PM/g'
На самом деле, вы можете сделать и :
, и PM
частью группы захвата:
sed 's/03\(:..PM\)/15\1/g'
Использование sed
$ sed '/[0-9:]*[AP]M/s/^[^:]*/15/' <<< $line
15:23PM
Или используйте решение @dawg для обработки нескольких диапазонов.
sed "/PM/s/^[^:]*/echo \$((&+12))/e" <<< $line
15:23PM
Возможно, вы захотите закрепить это в начале строки с помощью s/^[^:]...
.
А может быть точнее с чем-то вроде/^[0-9][0-9]*:[0-9][0-9]*[AP]M/s/^[^:]*/15/
. Но это, безусловно, правильный подход.
Я бы использовал awk
, чтобы вы получали фактическое дополнение и могли определять AM
против PM
:
echo '03:23PM
11:33PM
03:23AM' | awk 'BEGIN{FS=OFS = ":"} /PM/ && $1<12 {$1=$1+12} 1'
Отпечатки:
15:23PM
23:33PM
03:23AM
Отличное решение
Если вам нужно справиться с этой задачей в любом контексте, и принимая во внимание, что вам нужно всего лишь 00
-11
часов, вы можете использовать Perl:
perl -pe 's/(?<!\d)(0?\d|1[01])(?=:[0-5]?\d\s*PM)/$1+12/ge' file
См. демонстрация регулярных выражений. Подробности:
(?<!\d)
- цифра сразу слева не допускается(0?\d|1[01])
- Группа 1 ($1
): необязательное 0
и затем любая одна цифра, или 1
и 0
или 1
после нее (10
и 11
)(?=:[0-5]?\d\s*PM)
— положительный прогноз, который требует :
, необязательную цифру от 0
до 5
, а затем любую одну цифру, ноль или более пробелов и PM
подстроку сразу справа от текущего местоположения.Замена $1+12
— это выражение, которое суммирует найденное значение часа с 12
.
См. онлайн демо:
#!/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"
Выход:
Time: 12:23PM
Time: 15:23PM
Time: 23:23PM
Time: 12:23PM
Time: 13:45PM
Технически, 24-часовое представление
03:23PM
равно15:23
-- безPM
...