Chinaunix

标题: 查找文件t.txt文件内容包含good的行,删除good所在行及其向上数5行和向下数5行? [打印本页]

作者: vcdog    时间: 2013-12-31 16:24
标题: 查找文件t.txt文件内容包含good的行,删除good所在行及其向上数5行和向下数5行?
需求如下:查找文件t.txt文件内容包含good的行,删除good所在行及其向上数5行和向下数5行?

t.txt文件内容如下:

# cat t.txt
5882|3530
5883|3529
5884|3528
5885|3532
5886|3533
good
5887|3534
5888|3535
5889|3536


5891|3541
5892|3543
5893|3544
5894|3545
5895|3546
good
5896|3531
5897|3537
5898|3539
5899|3540
5900|3542


5901|3547
5902|3551
5903|3554
5904|3553
5905|3556
good
5906|3559
5907|3560
5908|3561
5909|3562
5910|3564

如何查找文件t.txt文件内容包含good的行,删除good所在行及其向上数5行和向下数5行?

目前,可以使用 # grep -A5 -B5 'good'  t.txt

但是,不知道如何实现删除?望各位指点一下。非常感谢!
作者: dn833    时间: 2013-12-31 16:36
不够5行的怎么处理?
作者: vcdog    时间: 2013-12-31 16:46
不够5行的,就取5行之内的行数删除就成。
作者: MMMIX    时间: 2013-12-31 17:00
本帖最后由 MMMIX 于 2013-12-31 17:04 编辑

回复 1# vcdog


    两个 good 之间隔的行数小于 5 和小于 10 的情况怎么处理?
作者: yestreenstars    时间: 2013-12-31 17:21
本帖最后由 yestreenstars 于 2013-12-31 17:25 编辑

try:
  1. awk '/good/{if(n>5)for(i=0;i++<n-5;)print a[i];k=1;n=0;next}k{if(++n==5)k=n=0;next}{a[++n]=$0}END{if(!k)for(i=0;i++<n;)print a[i]}'
复制代码

作者: jason680    时间: 2013-12-31 18:19
本帖最后由 jason680 于 2013-12-31 18:22 编辑

回复 1# vcdog


$ awk -vS=5 '{c++;for(n=0;n++<S;)a[n]=a[n+1];a[S+1]=$0}/good/{c=-S}c>S{print a[1]}END{for(n=c;n--;)print a[S-n+1]}' t.txt


$ awk -vS=4 '{c++;for(n=0;n++<S;)a[n]=a[n+1];a[S+1]=$0}/good/{c=-S}c>S{print a[1]}END{for(n=c;n--;)print a[S-n+1]}' t.txt
5882|3530

5891|3541
5900|3542


5901|3547
5910|3564

作者: tseesing    时间: 2013-12-31 18:24
本帖最后由 tseesing 于 2013-12-31 20:54 编辑
  1. grep -n 'good' t.txt | cut -d: -f1 | awk '{
  2.     if (NR == FNR)
  3.     {
  4.         goodline[$0]=0
  5.     } else {
  6.         allline[FNR]=$0
  7.     }
  8.     } END {
  9.         all_len=FNR
  10.         all_st=1
  11.         all_end=0
  12.         j=0
  13.         for (j in goodline)
  14.         {
  15.             for (; all_st < (j - 5); ++all_st)
  16.             {
  17.                 print allline[all_st];
  18.             }
  19.             all_st = j + 6
  20.         }
  21.         for (; all_st <= all_len; ++all_st)
  22.        {
  23.            print allline[all_st]
  24.        }

  25.     } ' - t.txt
复制代码
有点烂,头有点晕。担待下。
shell 不是万能的,你们考虑过 shell 的感受么
怪异点的需求用高级语言实在
作者: java_html    时间: 2013-12-31 18:53
sed好像可以。忘了
作者: yestreenstars    时间: 2013-12-31 19:06
回复 6# jason680
请用以下文本测试一下:
  1. 1
  2. good
  3. 1
  4. 2
  5. 3
  6. good
  7. 1
  8. 2
复制代码

作者: yjh777    时间: 2013-12-31 19:20
$ lines=`grep -n good  t.txt | awk -F: '{print $1}'`
$ for l in $lines; do eval echo {$((l-5<1?1:l-5))..$((l+5))}d; done | sed 's/ /\n/g' | sort -nu | sed -f - t.txt
作者: jason680    时间: 2014-01-02 09:29
回复 9# yestreenstars

thank you and modified to below:

$ awk -vS=1 '{c++;for(n=0;n++<S;)a[n]=a[n+1];a[S+1]=$0}/good/{c=-S}c>S{print a[1]}END{for(n=c;n-->0;)print a[S-n+1]}' FILE
2
2

$ cat FILE
1
good
1
2
3
good
1
2
   




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2