解析sed命令'sed p;n'执行逻辑:为何输出与预期不符?
Sed命令执行机制详解(针对你的三个案例)
案例1:无-n的p命令
% seq 4 | sed 'p' 1 1 2 2 3 3 4 4
逻辑明确:未加-n时,sed默认在每个处理周期末尾打印模式空间内容,p命令会额外打印一次当前模式空间的内容,因此每行输出两次。
案例2:加-n的p命令
% seq 4 | sed -n 'p' 1 2 3 4
-n选项禁用了sed的默认打印行为,只有p命令明确触发打印,因此每行仅输出一次,无重复。
案例3:p;n命令的执行流程
% seq 4 | sed 'p;n' 1 1 2 3 3 4
你之前的误解在于对n命令的行为判断,下面结合你看到的输出(BSD sed环境),拆解每一步执行逻辑:
逐行处理步骤
处理第1行(内容
1)- 读取
1到模式空间。 - 执行
p命令:打印模式空间内容 → 输出第一个1。 - 执行
n命令:读取下一行2覆盖模式空间,但当前周期的默认打印仍会执行,打印原模式空间的1→ 输出第二个1。 - 进入下一个周期,模式空间内容变为
2。
- 读取
处理第2行(内容
2)- 执行
p命令:打印模式空间内容2→ 输出2。 - 执行
n命令:读取下一行3覆盖模式空间,当前周期的默认打印被跳过,无额外输出。 - 进入下一个周期,模式空间内容变为
3。
- 执行
处理第3行(内容
3)- 执行
p命令:打印模式空间内容3→ 输出第一个3。 - 执行
n命令:读取下一行4覆盖模式空间,当前周期的默认打印执行,打印原模式空间的3→ 输出第二个3。 - 进入下一个周期,模式空间内容变为
4。
- 执行
处理第4行(内容
4)- 执行
p命令:打印模式空间内容4→ 输出4。 - 执行
n命令:尝试读取下一行,到达文件末尾(EOF),sed直接退出,跳过当前周期的默认打印,无额外输出。
- 执行
核心要点
n命令的核心作用是读取下一行覆盖模式空间,本身不会触发打印。- 不同sed版本(GNU/BSD)对
n命令是否跳过默认打印有差异:你使用的BSD sed中,n仅在读取到EOF时跳过默认打印,读取有效行时会交替触发/跳过默认打印,导致奇偶行的输出次数不同;而GNU sed中n会始终跳过当前周期的默认打印,输出会是1,2,3,4。
内容的提问来源于stack exchange,提问作者Faxopita
相关产品推荐
相关产品推荐

