sed命令`sed -n 'N ; s/#\n@/#--@/ ; P ; D'`执行流程与输出疑问
解析sed命令
sed -n 'N ; s/#\n@/#--@/ ; P ; D'的执行逻辑与输出差异 基础信息
目标sed命令
sed -n 'N ; s/#\n@/#--@/ ; P ; D' corruptData.txt
输入文件corruptData.txt内容
Header Line# @# @Data Line #1 Data Line #2# @ End of Data Lines# @
实际执行输出
Header Line#--@# @Data Line #1 Data Line #2#--@ End of Data Lines#--@
错误预期的核心问题
你之前的流程推导错误根源是对D命令的行为理解偏差:D并非清空整个模式空间,而是仅删除模式空间中第一个换行符之前的内容;若模式空间还有剩余内容,会直接作为下一轮循环的起始状态,而非重新读取新行。
正确逐行执行步骤
以下是完整的sed循环执行流程:
第一轮循环
- 初始模式空间为空,sed自动读取第一行:
Header Line# - 执行
N:读取第二行@#,模式空间变为:Header Line#\n@# - 执行
s/#\n@/#--@/:匹配到#\n@,替换后模式空间变为:Header Line#--@# - 执行
P:打印模式空间全部内容(无换行符):Header Line#--@# - 执行
D:模式空间无换行符,直接清空,第一轮循环结束。
第二轮循环
- 模式空间为空,sed读取第三行:
@Data Line #1 - 执行
N:读取第四行Data Line #2#,模式空间变为:@Data Line #1\nData Line #2# - 执行
s/#\n@/#--@/:未匹配到目标串,模式空间内容不变 - 执行
P:打印第一个换行符前的内容:@Data Line #1 - 执行
D:删除第一个换行符前的内容,模式空间剩余:Data Line #2#,第二轮循环结束。
第三轮循环
- 模式空间已有内容
Data Line #2#,执行N:读取第五行@,模式空间变为:Data Line #2#\n@ - 执行
s/#\n@/#--@/:匹配到目标串,替换后模式空间变为:Data Line #2#--@ - 执行
P:打印全部内容:Data Line #2#--@ - 执行
D:模式空间无换行符,直接清空,第三轮循环结束。
第四轮循环
- 模式空间为空,sed读取第六行:
End of Data Lines# - 执行
N:读取第七行@,模式空间变为:End of Data Lines#\n@ - 执行
s/#\n@/#--@/:匹配到目标串,替换后模式空间变为:End of Data Lines#--@ - 执行
P:打印全部内容:End of Data Lines#--@ - 执行
D:模式空间无换行符,直接清空,第四轮循环结束。
输出差异原因
你预期中Data Line #2#会被单独打印,但实际它在第二轮循环结束后被留在了模式空间,第三轮循环时N命令直接读取下一行@与之合并,触发了替换规则后才打印,这就是实际输出和你预期不符的核心原因。
内容的提问来源于stack exchange,提问作者Jack Ma
相关产品推荐
相关产品推荐

