【问题标题】:Bash script cut at specific ranges在特定范围内剪切的 Bash 脚本
【发布时间】:2017-01-16 08:52:56
【问题描述】:

我有一个包含大量收集日志的日志文件,我已经使用正则表达式创建了一个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 命令。

【问题讨论】:

  • 请从源头阐明范围的构成,并提供示例输入和输出。
  • 在考虑复杂的 grep 之前,您实际上首先尝试做什么?
  • 谢谢我更新了答案。
  • 请注意,您可以在一个 awksed 命令中完成所有操作。搜索sed/awk multiline matching

标签: bash shell awk sed grep


【解决方案1】:

您也可以使用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

【讨论】:

    【解决方案2】:

    使用sed,您可以像这样执行多个范围的行:

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

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

    【讨论】:

    • 是的,正在工作!当我尝试使用多个范围时,我错过了p。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    • 2012-11-29
    • 1970-01-01
    相关资源
    最近更新 更多