Shell 在两个固定模式之间显示数据

Shell 在两个固定模式之间显示数据,shell,awk,sed,Shell,Awk,Sed,我将随机数据从一个源输入到一个文件中。我必须通读文件,只提取属于特定模式的那部分数据 示例:假设文件myfile.out如下所示 info-data some more info-data ================================================================= some-data some-data some-data ===========================================================

我将随机数据从一个源输入到一个文件中。我必须通读文件,只提取属于特定模式的那部分数据

示例:假设文件
myfile.out
如下所示

info-data
some more info-data
=================================================================
some-data
some-data
some-data
=================================================================

======================= CONFIG PARMS : ==========================
some-data
some-data
some-data
=================================================================

======================= REQUEST PARAMS : ========================
some-data
some-data
some-data
=================================================================

===================== REQUEST RESULTS ===========================
some-data
=================================================================
some-data
some-data
=================================================================
Data-I-Need
Data-I-Need
...
...
...
Data-I-Need
==========================F I N I S H============================

some-info-data
我只是在寻找与这个特定模式匹配的数据

=================================================================
Data-I-Need
Data-I-Need
...
...
...
Data-I-Need
==========================F I N I S H============================
我确实试着四处看看,就像

但是这里给出的
awk
sed
解决方案似乎不起作用,命令没有给出任何错误或输出

我试过这个

PATTERN1="================================================================="
PATTERN2="==========================F I N I S H============================"
awk -v PAT1="$PATTERN1" -v PAT2="$PATTERN2" 'flag{ if (/PAT2/){printf "%s", buf; flag=0; buf=""} else buf = buf $0 ORS}; /PAT1/{flag=1}' myfile.out

也许是因为这种模式?或者我做错了什么


脚本将在RHEL 6.5上运行。

假设您只需要数据而不需要模式,使用GNU awk:

awk -v RS='\n={26,}[ A-Z]*={28,}\n' 'RT~/F I N I S H/' file
记录分隔符
RS
被设置为匹配一系列
=
行和其中一些可选大写字符


唯一的语句是检查(当前记录的)记录终止符
RT
是否包含
FINISH
关键字。如果是这样,awk将打印由多行组成的整个记录。

sed
可以处理此问题

假设您希望保留页眉和页脚行-

如果没有,请使用

请注意,如果您不使用GNU sed,则需要插入换行符,而不是所有这些分号。 分解它-

-En表示使用扩展模式匹配(即-E,我实际上只用于
+
),除非特别要求,否则不输出任何内容(即-n)

表示只在所有代码> >代码> >行之间执行这些命令,所有的代码都是<代码>=<代码>,除了在某个地方中的<代码> f i i s h < /代码>之外。

{}
之间的所有内容都将在它们之间的所有行上进行检查。这确实意味着从第一行开始,但没关系,我们在内部处理

(a) /^=+$/ { x; d; };
(b) /^=+$/ { s/.*//g; x; d; };
(a)
表示在所有
=
的每一行上,用“保留空间”交换(
x
)当前行(“模式空间”),然后删除(
d
)模式空间。这将保留当前行,并删除在错误开始时可能在上面累积的内容。(请记住-n在我们需要之前禁止打印任何内容。)

(b)
表示先擦除当前行,然后交换并删除。它仍然会添加一个换行符。你想把它去掉吗

/^[^=]/ { H; d; };
两个版本都使用这个。在任何不以
=
开头的行上,将其添加到保留空间(
H
),然后删除图案空间(
d
)。删除操作总是重新启动循环,读取下一条记录

(a) /^=+F I N I S H=+$/{ H; x; p; q; };
(b) /^=+F I N I S H=+$/{ x; p; q; };
在所有
=
之间带有sentinel
F I S H
字符串的任何行上,
(a)
将首先将模式附加(
H
)到保持空间-
(b)
将不会。然后两者都将交换图案和保留空间(
x
),打印(
p
)图案空间(现在是累积到保留空间中的值),然后删除(
d
)图案空间,触发下一个循环

此时,您将处于初始切换之外,因此除非发生另一行all
=
,否则您将跳过所有剩余的行。如果其中一条记录被删除,它将再次开始累积记录,但不会打印记录,除非它命中另一条
F I N I S H
记录

}' infile
这将关闭脚本并传入您使用的任何文件名。请注意,这不是就地编辑


希望能有所帮助。

虽然已经有了
sed
解决方案,但我喜欢
sed
的简单性:

sed -n '/^==*\r*$/,/^==*F I N I S H/{H;/^==*[^F=]/h;${g;p}}' file
在这个
sed
命令中,我们为要运行的命令设置了一个范围。此范围以一行开始,仅包含并结束于
=
,然后以
=
开始并指向
F I I S H
的行结束。现在我们的命令是:

H
立即追加每行以保留空格。然后在其他节的页眉或页脚上执行
/^==*[^F=]/h
,用当前模式空间替换保留空间

在最后一行,我们用保留空间中的内容替换当前模式空间,然后使用
${g;p}
打印它。整件事的结果是:

=================================================================
Data-I-Need
Data-I-Need
...
...
...
Data-I-Need
==========================F I N I S H============================
这可能适用于您(GNU-sed):


将仅包含
=
的行存储在保留空间中(替换以前存在的任何内容)。附加所有其他行以保留空间。如果当前行不是包含
=
后接
F I I s H
后接
=
的行,请将其删除。否则,请切换到保留空间,删除第一行和最后一行,然后打印剩余的。

您是否需要开始和结束模式以及数据?@oliv不,我不需要。我意识到,我给出的模式不是rite。。。。这是
FINISH
而不是
FINISH
。@Marcos我用新模式更新了答案。(您可以更改语句
RT~/…/
以匹配任何字符串)@Marcos什么不起作用?您确定使用GNU awk吗?它是GNU awk 3.1.7I,不需要页眉和页脚行。然后将结果输出到
sed'1d$d、 "由于某些原因,您的解决方案不起作用,我将进一步测试以了解原因。请详细说明。它不起作用,不能描述问题是什么,你是否得到任何结果,如果是,那是什么。不过,我支持@poton的回答。这背后有一个好主意。这对我不起作用,我将尝试在这方面做更多的测试。它做了什么?
(a) /^=+$/ { x; d; };
(b) /^=+$/ { s/.*//g; x; d; };
/^[^=]/ { H; d; };
(a) /^=+F I N I S H=+$/{ H; x; p; q; };
(b) /^=+F I N I S H=+$/{ x; p; q; };
}' infile
sed -n '/^==*\r*$/,/^==*F I N I S H/{H;/^==*[^F=]/h;${g;p}}' file
=================================================================
Data-I-Need
Data-I-Need
...
...
...
Data-I-Need
==========================F I N I S H============================
sed -r '/^=+$/h;//!H;/^=+F I N I S H=+$/!d;x;s/^[^\n]*\n|\n[^\n]*$//g' file