只替换一行的开头

Replace only the beginning of a line

我正在努力使用 sed 命令。 我正在努力实现这一目标:

Input: 03:23PM

Output: 15:23PM

我试过的 sed 命令:

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

要记住部分替换测试,请使用括号。要引用第一对括号,请使用 </code>:</p> <pre><code>sed 's/03:\(..\)PM/15:PM/g'

事实上,您可以将 :PM 部分都设为捕获组:

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

使用sed

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

或者使用@dawg解决方案来处理多个范围

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

我会使用 awk 所以你得到实际的加法并且可以检测 AMPM:

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

打印:

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

如果您需要在任何类型的上下文中处理此任务,并且考虑到您只需要处理 00-11 小时,您可以使用 Perl:

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

参见regex demo详情:

  • (?<!\d) - 不允许紧靠左边的数字
  • (0?\d|1[01]) - 第 1 组 (</code>):一个可选的 <code>0,然后是任何一个数字,或者 1 和一个 01 在它之后(1011
  • (?=:[0-5]?\d\s*PM) - 需要 : 的正向前瞻,一个从 05 的可选数字,然后是任何一个数字,零个或多个空格和 PM 紧接在当前位置右侧的子字符串。

+12 替换是一个将找到的小时值与 12 相加的表达式。

参见 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)/+12/ge' <<< "$text"

输出:

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

Time: 12:23PM
Time: 13:45PM