在shell脚本中从文件中提取数据

在shell脚本中从文件中提取数据,shell,Shell,我在一个文件中有很多数据,如下所示 alert tcp any any -> any any (msg: "test1"; sid:16521; rev:1;created_at 2010_07_30, updated_at 2016_07_01;) alert tcp any any -> any any (msg: "test2"; nocase; distance:0; sid:16521; rev:1;created_at 2010_10_30, updated_at 2

我在一个文件中有很多数据,如下所示

 alert tcp any any -> any any (msg: "test1"; sid:16521; rev:1;created_at 2010_07_30, updated_at 2016_07_01;)
 alert tcp any any -> any any (msg: "test2"; nocase; distance:0; sid:16521; rev:1;created_at 2010_10_30, updated_at 2013_07_11;)
 alert tcp any any -> any any (msg: "test3"; file_data; content:"clsid"; nocase; distance:0; created_at 2008_08_03, updated_at 2016_05_01;
请尝试以下操作:

sed-re的/^.*在[0-9+]创建。*在[0-9+]更新。*$/\1、\2/'input.txt
对于
input.txt

alert tcp any->any any(消息:“test1”;sid:16521;版本:1;于2010年7月30日创建,于2016年7月01日更新)
警报tcp any->any any(消息:“test2”;nocase;距离:0;sid:16521;版本:1;于2010年10月30日创建,于2013年7月11日更新)
警报tcp any->any any(消息:“test3”;文件数据;内容:“clsid”;nocase;距离:0;在2008年8月3日创建,在2016年5月1日更新;
输出:

2010\u 07\u 30、2016\u 07\u 01
2010_10_30, 2013_07_11
2008_08_03, 2016_05_01

更逐步的方法可能如下所示:

cat input.txt\
|grep-Eo'(创建|更新)_位于[0-9|]+'\
|切割-d'-f 2\
|sed'N;s/\N/,/'
在这里,我们使用
grep
只输出与给定正则表达式匹配的数据,
(创建|更新)_在[0-9+

  • (创建|更新)_at
    -匹配文本“创建_at”或文本“更新_at”
  • 紧接着是一个空格,然后是组中的多个字符:
    0123456789
中期产出:

于2010年7月30日创建
更新日期:2016年7月1日
于2010年10月30日创建
更新日期:2013年7月11日
于2008年8月3日创建
更新日期:2016年05月01日
cut
然后用于仅获取第二个字段(
-f2
),该字段由空格(
-d''
)分隔

输出:

2010\u 07\u 30
2016_07_01
2010_10_30
2013_07_11
2008_08_03
2016_05_01
最后,
sed
用于将每两行连接在一起(
N
),并将换行符替换为逗号空格(
s/\N/,/

输出:

2010\u 07\u 30、2016\u 07\u 01
2010_10_30, 2013_07_11
2008_08_03, 2016_05_01
尝试以下操作:

sed-re的/^.*在[0-9+]创建。*在[0-9+]更新。*$/\1、\2/'input.txt
对于
input.txt

alert tcp any->any any(消息:“test1”;sid:16521;版本:1;于2010年7月30日创建,于2016年7月01日更新)
警报tcp any->any any(消息:“test2”;nocase;距离:0;sid:16521;版本:1;于2010年10月30日创建,于2013年7月11日更新)
警报tcp any->any any(消息:“test3”;文件数据;内容:“clsid”;nocase;距离:0;在2008年8月3日创建,在2016年5月1日更新;
输出:

2010\u 07\u 30、2016\u 07\u 01
2010_10_30, 2013_07_11
2008_08_03, 2016_05_01

更逐步的方法可能如下所示:

cat input.txt\
|grep-Eo'(创建|更新)_位于[0-9|]+'\
|切割-d'-f 2\
|sed'N;s/\N/,/'
在这里,我们使用
grep
只输出与给定正则表达式匹配的数据,
(创建|更新)_在[0-9+

  • (创建|更新)_at
    -匹配文本“创建_at”或文本“更新_at”
  • 紧接着是一个空格,然后是组中的多个字符:
    0123456789
中期产出:

于2010年7月30日创建
更新日期:2016年7月1日
于2010年10月30日创建
更新日期:2013年7月11日
于2008年8月3日创建
更新日期:2016年05月01日
cut
然后用于仅获取第二个字段(
-f2
),该字段由空格(
-d''
)分隔

输出:

2010\u 07\u 30
2016_07_01
2010_10_30
2013_07_11
2008_08_03
2016_05_01
最后,
sed
用于将每两行连接在一起(
N
),并将换行符替换为逗号空格(
s/\N/,/

输出:

2010\u 07\u 30、2016\u 07\u 01
2010_10_30, 2013_07_11
2008_08_03, 2016_05_01

awk可以做得更简单一些:

awk 'NF{gsub(/[;)]/,"");print $(NF-2),$NF}' file
NF-所以我们只对有数据的字段进行操作

gsub-消除最后一项上的一些废话


打印最后三个和最后一个项目

awk可以做得更简单一些:

awk 'NF{gsub(/[;)]/,"");print $(NF-2),$NF}' file
NF-所以我们只对有数据的字段进行操作

gsub-消除最后一项上的一些废话


打印倒数第三项和倒数第三项一般来说,不要只描述你已经在使用的内容,而是描述它是如何失败的/它在哪些方面仍然需要工作。否则,这里实际上没有明确的问题。顺便说一句,
grep'^alert'
使
grep-v^#
没有意义——一行不能以
alert
开头,也不能以星号开头毕竟,t与
#
(另外,结合
awk
grep
sed
是多余的--
awk
可以做任何事
sed
grep
can)它的可能重复通常有助于不只是描述你已经在使用什么,而是描述它如何失败/在什么方面它仍然需要工作。否则,这里实际上没有一个明确的问题。顺便说一句,
grep'^alert'
使
grep-v^#
moot——一行不能以
alert
开头,也不能以
#。(另外,将
awk
grep
sed
结合起来是多余的--
awk
可以做任何事
sed
grep
可以)如果您试图在此处表示最佳实践,则可能会重复UOOC。@CharlesDuffy我已更新了第一个示例,不想过度混淆OP。如果您试图在此处表示最佳实践,则可能会希望转储UOOC。@CharlesDuffy我已更新了第一个示例,不想过度混淆OP。