如果块中有特定字符串(Windows中的awk),如何忽略文本 问题

如果块中有特定字符串(Windows中的awk),如何忽略文本 问题,awk,Awk,我们可以通过awk处理块内的字符串吗 如果开始和结束之间没有错误文本,则只应打印查找…文本 如果出现文本错误,我只想跳过该块 如果该块有错误文本,则应始终忽略该块,并应为其他块打印以查找开头的文本 在块之间,可以放置或不放置新行 输入 预期产量 答案是肯定的。最初发布的规格不太清楚,但您应该能够轻松地根据需要调整以下内容: awk '/^start$/{s=$0; next} /^end$/ {if (!error) {print s; print $0; }; error=s=""; n

我们可以通过awk处理块内的字符串吗

如果
开始
结束
之间没有
错误
文本,则只应打印
查找…
文本

如果出现文本
错误
,我只想跳过该块

如果该块有
错误
文本,则应始终忽略该块,并应为其他块打印以
查找
开头的文本

在块之间,可以放置或不放置新行

输入 预期产量 答案是肯定的。最初发布的规格不太清楚,但您应该能够轻松地根据需要调整以下内容:

awk '/^start$/{s=$0; next}
  /^end$/  {if (!error) {print s; print $0; }; error=s=""; next}; 
  /error/  {error=1; next}
  !error   {s=s RS $0}'
通过您的输入,这将产生:

start

find_me2

end

(您表示希望包含“开始”和“结束”,因此我已将它们连同随附的整个文本块一起包含在内。)

您已经有了一个awk解决方案,下面是一个(GNU)sed解决方案:

$ awk '/^end$/&&fl{print st"#"$0;st=""}/^start$/{fl=1;st=$0}/^error$/{fl=0}/^find/{st=st"#"$0}' infile
start#find_me2#end
$sed-rn'/^start/{:a;N;/\N错误$/d;/\nend$/{s/^(开始)。*\N(查找。*)\N.*\N(结束)$/\1\3/p};ba}
开始#找到我2#结束
这样做的目的如下:

  • -n
    禁止打印,除非明确指示
  • -r
    可以在不转义括号的情况下捕获组,
    (…)
    而不是
    \(…)

以及一个替代awk解决方案:

$ awk '/^end$/&&fl{print st"#"$0;st=""}/^start$/{fl=1;st=$0}/^error$/{fl=0}/^find/{st=st"#"$0}' infile
start#find_me2#end
工作原理如下,稍微扩展:

# If the line matches 'end' and the flag is set
/^end$/ && flag {
    print str "#" $0  # Print string, append '#' and the line
    str = ""          # Reset string to empty
}

# If the line matches 'start'
/^start$/ {
    flag=1     # Set the flag
    str = $0   # Add line to string
}

# If the line matches 'error'
/^error$/ { 
    flag = 0   # Set the flag to zero, we don't want to print this block
}

# If the line matches 'find'
/^find/ { 
    str = str "#" $0    # Append '#' and line to string
}

这不太清楚。总是
找我
什么吗?在
开始
结束
之间还有其他词吗?对不起,把你弄糊涂了。是的,在开始和结束之间也可以有其他文本。我更新了问题。谢谢。如果第二块有
find_me1
,我也应该打印它。再次更新问题。谢谢。文本块之间总是有换行符吗?它似乎非常符合我的需要。你能解释一下这个部分[error=s=”“]和你的想法吗?谢谢。(1)error=s=“”只是error=“”的简写形式;s=“”;(2) 大致说来,总体思路是在变量s中累积块内的行,并在块内检测到“错误”时设置标志(即,名为“错误”的变量)。(3) 这个脚本有意地局限于awk基础知识,这些知识很容易掌握。一旦你掌握了基本知识,将这样的脚本改编成你描述的任务应该很容易。非常感谢。我明白这一点。这让我非常清楚地了解它是如何工作的。非常感谢。
$ awk '/^end$/&&fl{print st"#"$0;st=""}/^start$/{fl=1;st=$0}/^error$/{fl=0}/^find/{st=st"#"$0}' infile
start#find_me2#end
# If the line matches 'end' and the flag is set
/^end$/ && flag {
    print str "#" $0  # Print string, append '#' and the line
    str = ""          # Reset string to empty
}

# If the line matches 'start'
/^start$/ {
    flag=1     # Set the flag
    str = $0   # Add line to string
}

# If the line matches 'error'
/^error$/ { 
    flag = 0   # Set the flag to zero, we don't want to print this block
}

# If the line matches 'find'
/^find/ { 
    str = str "#" $0    # Append '#' and line to string
}