簡體   English   中英

SED:在比賽前解決兩條線路問題

[英]SED: addressing two lines before match

打印線,位於比賽前2行(圖案)。

我試過下一個:

sed -n ': loop
/.*/h
:x
{n;n;/cen/p;}
s/./c/p
t x
s/n/c/p
t loop
{g;p;}
' datafile

劇本:

  sed -n "1N;2N;/XXX[^\n]*$/P;N;D"

工作原理如下:

  • 前三行讀入模式空間, 1N;2N
  • 在最后一行的任何地方搜索測試字符串XXX ,如果找到則打印模式空間的第一行, P
  • 將下一行輸入附加到模式空間N
  • 從模式空間中刪除第一行並重新啟動循環而不進行任何新讀取, D ,注意1N;2N不再適用

這可能適合你(GNU sed):

sed -n ':a;$!{N;s/\n/&/2;Ta};/^PATTERN\'\''/MP;$!D' file

這將在整個文件中的PATTERN之前打印2行。

這個用grep,有點簡單的解決方案,易於閱讀[但需要使用一個管道]: grep -B2 'pattern' file_name | sed -n '1,2p' grep -B2 'pattern' file_name | sed -n '1,2p'

如果你可以使用awk試試這個:

awk  '/pattern/ {print b} {b=a;a=$0}' file

這將在pattern之前打印兩行

我已經測試了你的命令,但結果很奇怪(顯然是錯誤的),你沒有給出任何解釋。 您必須在緩沖區(命名保留空間 )中保存三行,使用最新行進行模式搜索,如果匹配則打印最舊的行:

sed -n '
    ## At the beginning read three lines.
    1 { N; N }
    ## Append them to "hold space". In following iterations it will append
    ## only one line.
    H 
    ## Get content of "hold space" to "pattern space" and check if the 
    ## pattern matches. If so, extract content of first line (until a 
    ## newline) and exit.
    g
    /^.*\nsix$/ { 
        s/^\n//
        P
        q 
    }
    ## Remove the old of the three lines saved and append the new one.
    s/^\n[^\n]*//
    h
' infile

假設並輸入以下內容的文件( infile ):

one
two
three
four
five
six
seven
eight
nine
ten

它將搜索six並且輸出將產生:

four

以下是一些其他變體:

awk '{a[NR]=$0} /pattern/ {f=NR} END {print a[f-2]}' file

這將所有行存儲在數組a 找到模式時存儲行號。
然后在文件中打印該行號。
對於大文件,PS可能會很慢


這是另一個:

awk 'FNR==NR && /pattern/ {f=NR;next} f-2==FNR' file{,}

這會讀取文件兩次( file{,}file file相同)
在第一輪,它在變量f找到模式和存儲行號
然后在第二輪,它在f的值之前打印第二行

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM