用sed代替正则表达式匹配&匹配前的一行“ - = + REMOVED + = - ”

时间:2013-09-17 13:01:59

标签: regex bash sed awk

我有一个很大的,我的意思是超过190万行的大对数。 我需要正则表达式替换所有不包含单词“Never”和前一行的行,然后替换为 - = + REMOVED + = - 。波纹管是日志中的一个例子。

2013-09-17-01:02:43 User: ID_123456@some.tld  
2013-09-17-01:02:43 Last login time: Never  
2013-09-17-01:02:43 User: ID_123458@some.tld  
2013-09-17-01:02:43 Last login time: 2013-09-16  
2013-09-17-01:02:43 User: ID_123423@some.tld  
2013-09-17-01:02:43 Last login time: 2013-09-15  

因此,用户有登录时间,删除电子邮件地址之前的行和行。最终输出应该看起来像

2013-09-17-01:02:43 User: ID_123456@some.tld  
2013-09-17-01:02:43 Last login time: Never  
-=+ REMOVED +=-  
-=+ REMOVED +=-  
-=+ REMOVED +=-  
-=+ REMOVED +=-  

应该很容易,但过去一小时我一直在绞尽脑汁。

我更喜欢使用sed,因为我正在尝试了解更多内容,但我愿意接受任何事情......

3 个答案:

答案 0 :(得分:4)

这可能适合你(GNU sed):

 sed '$!N;/\n.*Never/!s/.*/-=+ REMOVED +=-/mg'  file

答案 1 :(得分:1)

这可以做到:

$ rm="-=+ REMOVED +=-"
$ awk -v rm="$rm" 'BEGIN{OFS="\n"}NR%2{a=$0; next} $0~/Never/ {print a,$0; next}{print rm,rm}' a
2013-09-17-01:02:43 User: ID_123456@some.tld  
2013-09-17-01:02:43 Last login time: Never  
-=+ REMOVED +=-
-=+ REMOVED +=-
-=+ REMOVED +=-
-=+ REMOVED +=-

解释

  • -v rm="$rm"用于存储“已删除”文字。
  • BEGIN{OFS="\n"}定义行分隔符。
  • NR%2{a=$0; next}如果是奇数行,请将该行存储在a var中。 $ 0~ / Never / {打印,$ 0;下一步} {print rm,rm}'in case the line contains "Never", print the previous line (stored in and the current one). Otherwise, print已删除`文字两次。

答案 2 :(得分:0)

另一个awk

awk '/User:/ {u=$0} /Last/ {if (/Never/) {print u"\n"$0} else {print v"\n"v}}' v="-=+ REMOVED +=-" file