awk和多行匹配(子正则表达式)

awk和多行匹配(子正则表达式),awk,Awk,我正在尝试使用awk解析多行表达式。其中一个看起来像这样: _begin hello world ! _attrib0 123 _attrib1 super duper _attrib1 yet another value _attrib2 foo _end 我需要提取与_begin和_attrib1关联的值。因此,在本例中,awk脚本应返回(每行一个): 使用的分隔符是制表符(\t)字符。空格仅在字符串中使用。以下awk脚本执行此任务: #!/usr/bin/awk

我正在尝试使用awk解析多行表达式。其中一个看起来像这样:

_begin  hello world !
_attrib0    123
_attrib1    super duper
_attrib1    yet another value
_attrib2    foo
_end
我需要提取与_begin和_attrib1关联的值。因此,在本例中,awk脚本应返回(每行一个):


使用的分隔符是制表符(\t)字符。空格仅在字符串中使用。

以下awk脚本执行此任务:

#!/usr/bin/awk -f
BEGIN { FS="\t"; }
/^_begin/      { output=$2; }
$1=="_attrib1" { output=output " " $2; }
/^_end/        { print output; }
您没有指定是否希望选项卡(
\t
)作为输出字段分隔符。如果有,请告诉我,我会更新答案。(或者你可以;这很琐碎。)

当然,如果你想要一个可怕的替代方案(因为我们快到万圣节了),这里有一个使用
sed
的解决方案:

$ sed -ne '/^_begin./{s///;h;};/^_attrib1[^0-9]/{s///;H;x;s/\n/ /;x;};/^_end/{;g;p;}' input.txt 
hello world ! super duper yet another value
这是怎么回事?姆瓦哈哈,很高兴你问我

  • 开始--当我们看到
    \u begin
    时,将其剥离并将行的其余部分存储到sed的“hold buffer”中
  • /^属性1[^0-9]/{s//;H;x;s//\n//;x;}--当我们看到
    \u attrib1
    时,将其剥离,附加到保留缓冲区,交换保留缓冲区和模式空间,用空格替换换行,然后再次交换保留缓冲区和模式空间
  • /^\u end/{;g;p;}
    --我们已经到了末尾,所以将保持缓冲区拉入模式空间并打印它
这假设输入字段分隔符只是一个选项卡

这么简单。谁说过sed是神秘的

这应该有效:

#!/bin/bash 

awk 'BEGIN {FS="\t"} {if ($1=="_begin" || $1=="_attrib1") { output=output " " $2 }} END{print output}'

_attrib11正在使此脚本失败(_attrib1匹配)。您提供的示例数据中没有
_attrib11
。如果愿意,您可以使用
$1==“\u attrib1”
等条件来处理该问题,而不是
/^\u attrib1/
,或者您可以将其保留为正则表达式,但终止它,如
$1~/^\u attrib1$/
。我推荐第一种替代方案;始终先选择字符串匹配,再选择正则表达式(至少)。根据您的新要求更新我的答案。为了您的阅读乐趣,还添加了一个
sed
备选方案。@ghoti,您的第一个示例对我不适用。只打印空行。为什么?@Tedee12345-可能与您的输入数据有关。为什么不,我们看看能做些什么?
#!/bin/bash 

awk 'BEGIN {FS="\t"} {if ($1=="_begin" || $1=="_attrib1") { output=output " " $2 }} END{print output}'