Bash脚本在特定范围内切割

时间:2017-01-16 08:52:56

标签: bash shell awk sed grep

我有一个包含大量收集日志的日志文件,我已经使用正则表达式创建了grep命令,该命令输出与其匹配的行数。 这是我用来输出匹配行的grep命令:

grep -n -E 'START_REGEX|END_REGEX' Example.log | cut -d ':' -f 1 > ranges.txt

正则表达式是有条件的,它可以匹配特定日志或其结束的开头,因此输出类似于:

12
45
128
136
...

这个想法是使用它作为范围的来源,在日志文件中从第一个数字到第二个数字进行特定剪切并将它们保存在另一个文件中。
范围由输出的耦合产生,根据示例,第一范围是12,45,第二范围是128,136。 我希望在最终文件中看到来自行12 to 45然后来自128 to 136的所有文本。 我面临的问题是sed命令似乎只能在一个范围内使用。

sed -E -iTMP "$START_RANGE,$END_RANGE! d;$END_RANGEq" $FILE_NAME

有没有办法(可能有awk)只在一个“周期”中做到这一点? 约束:我只能使用支持的bash命令。

2 个答案:

答案 0 :(得分:2)

使用sed,您可以执行多个范围的行,如下所示:

sed -n '12,45p;128,136p'

这将输出12-45行,然后输出128-136。

答案 1 :(得分:2)

您也可以使用awk语句

awk '(NR>=12 && NR<=45) || (NR>=128 && NR<=136)' file

其中,NRAwk中的一个特殊变量,它在处理文件时保留行号的跟踪。

一个例子,

seq 1 10 > file
cat file
1
2
3
4
5
6
7
8
9
10
awk '(NR>=1 && NR<=3) || (NR>=8 && NR<=10)' file
1
2
3
8
9
10

您还可以使用-v变量选项

来避免对行号进行硬编码
awk -v start1=1 -v end1=3 -v start2=8 -v end2=10 '(NR>=start1 && NR<=end1) || (NR>=start2 && NR<=end2)' file
1
2
3
8
9
10