亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: awk 實現(xiàn) grep -A3 -B3 的效果,文本10G行 [打印本頁]

作者: unixzhong    時間: 2011-03-23 10:12
標(biāo)題: awk 實現(xiàn) grep -A3 -B3 的效果,文本10G行
比如 grep -A3 -B3  B  text.txt

我自己的解法如下,但想集思廣益下,應(yīng)該有其他的思路, 并且,我這個方法,如果文本行數(shù)在 10G級別的話,那得耗費多少內(nèi)存呀?

{ ra[NR]=$0}
/B/{ for(i=NR-3;i<=NR+3;i++){if(i>0)ln_pflag[i]=1} }
END { for(j=1;j<=NR;j++){ if(ln_pflag[j]==1)print ra[j] } }
作者: yinyuemi    時間: 2011-03-23 10:24
本帖最后由 yinyuemi 于 2011-03-23 23:24 編輯
  1. awk '{a[NR]=$0}/B/{for(i=NR-3;i<NR;i++)print a[i];print;for(j=1;j<=3;j++) {getline;print};exit}'
復(fù)制代碼

作者: ziyunfei    時間: 2011-03-23 10:29
awk '/B/{for(i in a){print a[i]}for(i in a){getline;print}}{a[NR%3]=$0}'

前三行沒順序
作者: ziyunfei    時間: 2011-03-23 10:31
需要順序的話 可以改改
作者: yinyuemi    時間: 2011-03-23 10:35
sed -n '
/B/ !{
H
x
s/^.*\n\(.*\n.*\n.*\)$/\1/
x}
/B/{
H
n
H
n
H
n
H
n
x
p
q}' file
作者: L_kernel    時間: 2011-03-23 12:31
使用grep的參數(shù)--line-buffered,看看能不能加快速度~~
作者: unixzhong    時間: 2011-03-23 14:22
本帖最后由 unixzhong 于 2011-03-23 14:24 編輯

回復(fù) 2# yinyuemi

你這個比我的簡潔,

不過假如連續(xù)兩行都有 B匹配命中
你這樣,好像會重復(fù)打印部分行, 和 grep -A3 -B3 B 的效果還是有點不一樣, 不知道我說清楚沒有

不會sed,因為我記性差,同時學(xué) sed 和 awk老是搞混語法,:)
作者: blackold    時間: 2011-03-23 14:41
這個得先搞清楚grep -A -B。重疊時比較麻煩吧。
作者: yinyuemi    時間: 2011-03-23 14:46
回復(fù) 7# unixzhong


    可以舉個例子么
作者: unixzhong    時間: 2011-03-23 15:39
回復(fù) 8# blackold

黑哥:

我的代碼已經(jīng)可以處理 重疊的情況了,就是想看看有沒有其他 思路,當(dāng)然我希望是awk實現(xiàn),我不懂sed,:(


yinyuemi:

1111
222
333
4444
5555
B
B
8888
9999
aaaaa
bbbbbb
ccccc
作者: blackold    時間: 2011-03-23 18:06
回復(fù) 10# unixzhong
  1. awk -f grepC.awk urfile
復(fù)制代碼
grepC.awk
  1. {
  2.     if (/B/) {
  3.         if (!f) {
  4.             if (p) {
  5.                 if ( mN && NR - lpN > 3) print "--";
  6.                 print p;
  7.                 p = "";
  8.             }
  9.             f = !f;
  10.         }
  11.         mN = NR;
  12.         print;
  13.         lpN = NR;
  14.     } else if (f) {
  15.         if (NR-mN > 3) {
  16.             f = !f;
  17.             if (gsub(/\n/,"\n",p) > 1) sub(/[^\n]*\n/,"",p);
  18.             p = p?p"\n"$0:$0;
  19.         } else {
  20.             print;
  21.             lpN = NR;
  22.         }
  23.     } else {
  24.         if (gsub(/\n/,"\n",p) > 1) sub(/[^\n]*\n/,"",p);
  25.         p = p?p"\n"$0:$0;
  26.     }
  27. }
復(fù)制代碼

作者: yinyuemi    時間: 2011-03-24 01:53
本帖最后由 yinyuemi 于 2011-03-26 01:23 編輯
回復(fù)  blackold

黑哥:

我的代碼已經(jīng)可以處理 重疊的情況了,就是想看看有沒有其他 思路,當(dāng)然我希望 ...
unixzhong 發(fā)表于 2011-03-23 15:39
  1. awk '{a[++p]=$0}

  2. /B/{p>f+3;print "-----"

  3.         f=p;

  4.         for(i=p-3;i<=p;i++)

  5.                 if((!(i in b))&&a[i]){print a[i];b[i]}

  6.     }

  7. NR==f+3&&f{

  8.         for(k=NR-2;k<=NR;k++)

  9.                 if((!(k in b))&&a[k]){print a[k];b[k]}

  10.              }'
復(fù)制代碼
這個應(yīng)該會快點
作者: blackold    時間: 2011-03-24 10:07
剛才做了測試,grep快很多,有時間可以看看grep的源碼。
作者: yinyuemi    時間: 2011-03-24 10:14
剛才做了測試,grep快很多,有時間可以看看grep的源碼。
blackold 發(fā)表于 2011-03-24 10:07



    恩,我也測試了,
seq 1000000 |awk 'END{print}'

seq 1000000 | grep -A3 -B3 -w 5000
用的時間幾乎一樣
作者: unixzhong    時間: 2011-03-25 18:19
本帖最后由 unixzhong 于 2011-03-25 18:48 編輯

回復(fù) 11# blackold


    快速掃描了下黑哥代碼,發(fā)現(xiàn)的確沒有用 a[NR]=$0
心里肯定了, 有不那么耗費內(nèi)存的方式。
(  我一樓代碼里面  那種方式吃太多內(nèi)存 ----------------數(shù)組保存所有行)

再看了下 黑哥代碼,自己功力太淺,看的有點頭暈,因為沒有 了解 黑哥的思路。

就暫時不敢回貼了。

后來就放一邊了, 看其他awk代碼去了,嘿嘿,從 tail -n 2 的awk實現(xiàn)例子里,得到了一點啟發(fā)。

于是 有了下面的  我的新實現(xiàn)了 (只需要一個 小 數(shù)組 臨時 保存 當(dāng)前行 和 它的前3行即可  )

經(jīng)過驗證,才敢貼上來

man find | awk -f mygrep_atime_nodebug.awk  > mygrep_output

man find |  grep -A3 -B3  atime  > grep_output

diff mygrep_output  grep_output 沒輸出 :)
  1. BEGIN { Last_Range_End=0; Range_End=0;  for(i=0;i<=3;i++)keep[i]="" }


  2. {for(j=3;j>0;j--)keep[j]=keep[j-1];  keep[0]=$0}
  3. NR<=Range_End { print $0 }



  4. /atime/{ Last_Range_End=Range_End; Range_End= NR + 3;

  5.                 if (  Last_Range_End < NR )
  6.                          {
  7.                         non_intersect_lines=(4 - (NR - Last_Range_End) )>0? (NR - Last_Range_End) :4 ;
  8.                         if(non_intersect_lines==4) print "--" ;  
  9.                         for(i=non_intersect_lines-1;i>=0;i--) print keep[i]
  10.                         }
  11.           }
復(fù)制代碼
回家
作者: unixzhong    時間: 2011-03-25 18:27
回復(fù) 14# yinyuemi


    謝謝  yinyuemi  一直以來的 熱心探討

     第一次知道 有 seq這個命令,

     能 就 如何 測量  腳本效率, 簡單地 說說嗎? 我還從來沒 這樣的經(jīng)歷, 多謝了。
作者: yinyuemi    時間: 2011-03-26 01:28
本帖最后由 yinyuemi 于 2011-03-26 12:18 編輯

回復(fù) 16# unixzhong


  這個.... , 還是高手解答吧, 時間應(yīng)該算個很直觀的標(biāo)準(zhǔn)!
作者: blackold    時間: 2011-03-29 12:05
回復(fù) 15# unixzhong


    你用經(jīng)典的數(shù)據(jù)來測試, 就發(fā)現(xiàn)和grep的輸出有差別了。
作者: 南極雨    時間: 2011-03-31 17:51
回復(fù) 5# yinyuemi

經(jīng)。!
作者: MeaCulpa    時間: 2011-04-01 14:39
既然是Awk就可以用Awk way, 扔給awk自己處理不知道會不會快一些:

  1. awk 'BEGIN{FS="\n"; RS=EOF} {代碼}'
復(fù)制代碼





歡迎光臨 Chinaunix (http://72891.cn/) Powered by Discuz! X3.2