使用 awk 或 sed 取消注释文本块

Uncomment a block of text with awk or sed

假设我有一个像这个例子的文本文件:

Lorem ipsum dolor sit amet, nullam euismod tractatos id mel, has integre ornatus 
feugait ad. In eum enim putent fierent. Quo melius persecuti conceptam eu, ne probo 
autem inciderint quo, ius et atqui diceret. Causae prompta corpora ex ius. Atqui 
aperiri in duo, ex pro reque utinam.

Sea ne prima falli petentium. Ut has ancillae omnesque lucilius, vim ex alia 
audire contentiones. Error possit singulis at his. Ne purto soleat ius, detracto 
sententiae mel ne. Te eos regione detracto, eam quas accumsan detracto an.

  # Lorem ipsum dolor sit amet, nullam euismod tractatos id mel, has integre ornatus 
  # feugait ad. In eum enim putent fierent. Quo melius persecuti conceptam eu, ne probo 
  # autem inciderint quo, ius et atqui diceret. Causae prompta corpora ex ius. Atqui 
  # aperiri in duo, ex pro reque utinam.

  # Comment
  # At debet expetenda sed, sed te case ceteros adolescens. Ad sea facer minim tempor, 
  # eam facilisi definitiones ei, vix vidit erant dissentias et. Eum fierent scaevola 
  # suscipiantur eu. Eum essent platonem interesset ex, ut idque vidisse nam, labores 
  # intellegam comprehensam eos et. Eu eum appetere sententiae percipitur, ad eam hinc 
  # impetus sententiae, pro duis consetetur reprehendunt in. Id percipit iracundia 
  # abhorreant est.

  # Sea ne prima falli petentium. Ut has ancillae omnesque lucilius, vim ex alia 
  # audire contentiones. Error possit singulis at his. Ne purto soleat ius, detracto 
  # sententiae mel ne. Te eos regione detracto, eam quas accumsan detracto an.

Lorem ipsum dolor sit amet, nullam euismod tractatos id mel, has integre ornatus 
feugait ad. In eum enim putent fierent. Quo melius persecuti conceptam eu, ne probo 
autem inciderint quo, ius et atqui diceret. Causae prompta corpora ex ius. Atqui 
aperiri in duo, ex pro reque utinam.

Sea ne prima falli petentium. Ut has ancillae omnesque lucilius, vim ex alia 
audire contentiones. Error possit singulis at his. Ne purto soleat ius, detracto 
sententiae mel ne. Te eos regione detracto, eam quas accumsan detracto an.

我想使用 AWK 或 SED 取消注释行 # Comment 之后的下 3 行,因此它最终看起来像这样:

  # Comment
  At debet expetenda sed, sed te case ceteros adolescens. Ad sea facer minim tempor, 
  eam facilisi definitiones ei, vix vidit erant dissentias et. Eum fierent scaevola 
  suscipiantur eu. Eum essent platonem interesset ex, ut idque vidisse nam, labores 
  # intellegam comprehensam eos et. Eu eum appetere sententiae percipitur, ad eam hinc 
  # impetus sententiae, pro duis consetetur reprehendunt in. Id percipit iracundia 
  # abhorreant est.

请解释您的解决方案,以便我学习和理解。我对AWK和SED的了解还处于初级水平。

这是我使用 GNU sed 的尝试(这可能不适用于其他版本的 sed):

sed '/^  # Comment$/,+3 { s/^  # /  /; s/^  Comment$/  # Comment/ }'

我们匹配以等于 " # Comment" 的行开始的所有行以及之后的下 3 行(+3 部分是 GNU 扩展,我的手册说)。

在这些行中,我们将前导 " # " 替换为两个空格 " ",从而取消注释该行。

但是,这也会影响您不想取消注释的起始行。所以我们在之后修复它:如果结果行是 " Comment",我们将 "# " 添加回去。

awk 在其 NR 变量中计算行数。

awk '/# Comment/ {n=NR}
     n && NR-n && NR-n<=3 {sub("# ?","")}
     {print}'

n=NR 捕获 # Comment 出现的行号

零相当于 false,非零相当于 awk 中的真,所以在条件中:1) n 防止从文件开头开始取消注释,2) NR-n 防止从 # Comment 行开始取消注释,并且 3) NR-n<=3 定义确实发生取消注释的行。

函数sub是awk的一次性字符串替换。要替换为“”的字符串,即删除,是注释符号 # 后跟零或一个空格 -- ? 是 "optional" 的正则表达式量词(零或一) .