簡體   English   中英

grep / pcregrep / sed / awk最后一次匹配到文件末尾后的數據

[英]grep/pcregrep/sed/awk the data after the last match to the end of a file

我需要在ENTRY的最后一個匹配到文件末尾之后抓取內容,我似乎無法做到。 它可以是多行,數據可以包含文件末尾的任何字符,包括(,\\ n,)。

我試過了:

tail -1 file # doesn’t work due to it not consistently being one line
grep "^(.*"  # only grabs one line
pcregrep -M  '\n(.*' file # I think a variation of this is the solution, but I’ve had no luck so far.  

文件增長如下:

TOP OF FILE                
%
ENTRY
(S®s
√6ûíπ‹ôTìßÅDPˆ¬k·Ù"=ÓxF)*†‰ú˚ÃQ´¿J‘\˜©ŒG»‡∫QÆ’<πsµ-ù±ñ∞NäAOilWçk
N+P}V<ôÒ∏≠µW*`Hß”;–GØ»14∏åR"ºã
FD‘mÍõ?*ÊÎÉC)(S®s
√6ûíπ‹ôTìßÅDPˆ¬k·Ù"=ÓxF)*†‰ú˚ÃQ´¿J‘\˜©ŒG»‡∫QÆ’<πsµ-ù±ñ∞NäAOilWçk
N+P}V<ôÒ∏≠µW*`Hß”;–GØ»14∏åR"ºã
FD‘mÍõ?*ÊÎÉC)eq  
{
DATA
}
ENTRY
(A® S\kÉflã1»Âbπ¯Ú∞⁄äπHZ@F◊§•Ã*‹¡‹…ÿPkJòÑíòú˛¶à˛¨¢v|u«Ùbó–Ö¶¢∂5ıÜ@¨•˘®@W´≥‡*`H∑”ı–Só¬<˙ìEçöf∞Gg±:œe™flflå)A®  S\kÉflã1»Âbπ¯Ú∞⁄äπHZ@F◊§•Ã*‹¡‹…ÿPkJòÑíòú˛¶à˛¨¢v|u«Ùbó–Ö¶¢∂5ıÜ@¨•˘®@W´≥‡*`H∑”ı–Só¬<˙ìEçöf∞Gg±:œe™flflå)eq  
{
DATA
}if
ENTRY
(ÌSYõ˛9°\K¬∞≈fl|”/í÷L
Ö˙h/ÜÇi"û£fi±€ÀNéÓ›bÏÿmâ[≈4J’XPü´Z
oÜlø∫…qìõ¢,ßü©cÓ{—˜e&ÚÀÓHÏÜ‚m(Œ∆⁄ˆQ˝òêpoÉÄÂ(S‘E ⁄ !ŸQ§ô6ÉH
$ awk '/^[(]/{s="";} {s=s"\n"$0;} END{print substr(s,2);}' file
(ÌSYõ˛9°\K¬∞≈fl|”/í÷L
Ö˙h/ÜÇi"û£fi±€ÀNéÓ›bÏÿmâ[≈4J’XPü´Z
oÜlø∫…qìõ¢,ßü©cÓ{—˜e&ÚÀÓHÏÜ‚m(Œ∆⁄ˆQ˝òêpoÉÄÂ(S‘E ⁄ !ŸQ§ô6ÉH

這個怎么運作

awk隱式循環遍歷文件。 該腳本存儲我們想要在變量s打印的任何內容。

  • /^[(]/{s="";}

    每次我們找到一個以(s開頭)為空字符串的行。

    這樣做的目的是在最后一次以( 。開頭)出現的行之前刪除所有內容。

  • s=s"\\n"$0

    我們將當前行添加到s的末尾。

  • END{print substr(s,2);}

    在我們到達文件末尾之后,我們打印s (省略第一個字符,它將是一個多余的換行符)。

有趣的問題。 我認為你可以用sed做到這一點。 找到匹配項時,將保留空間歸零並將匹配線添加到保留空間。 在最后一行,打印保留空間。

sed -n -e '/ENTRY/,$ { /ENTRY/ { h; n; }; H; $ { x; p; } }'

默認情況下不打印。 從文件的第一個條目到結尾:

  • 如果是入境線; 將新線復制到保留空間並繼續。
  • 否則將該行附加到保留空間。
  • 如果它是最后一行,則交換保留空間和圖案空間,然后打印圖案空間(保留空間中的內容)。

如果文件中的最后一行是ENTRY行,您可能會擔心會發生什么。

給定一個data文件:

TOP OF FILE
not wanted
ENTRY
could be wanted
ENTRY
but it wasn't
and this isn't
because
ENTRY
this is here
EOF

輸出是:

ENTRY
this is here
EOF

如果您不想顯示ENTRY ,請稍微修改腳本:

sed -n -e '/ENTRY/,$ { /ENTRY/ { s/.*//; h; n; }; H; $ { x; s/^\n//; p; } }'

使用tac你可以做到:

tac <file> | sed -e '/ENTRY/,$d' | tac

這將打印帶有反轉行的文件,然后使用sed刪除從現在第一次出現的ENTRY到文件現在結束的所有內容,然后再次反轉這些行以獲得原始順序。

正如喬納森·萊弗勒所指出的那樣,一種更快的方法 - 雖然可能並不多,因為tac仍然有很多工作要做,並且它需要獲得3個進程而不僅僅是一個進程的所有開銷,但是sed可以更有效地完成,但只是在我們找到ENTRY行時結束,而不是處理文件的其余部分以刪除行:

tac <file> | sed -e '/ENTRY/q' | tac

雖然他的回答往往會更好。 答案將包括ENTRY系列。 如果你不想要你也可以

tac <file> | sed -n '/ENTRY/q;p' | tac

默認情況下不打印任何ouptut,然后在找到ENTRY行后立即退出,但使用p命令打印行,直到到達該行。

這也應該工作(至少與gawk)

awk -vRS="ENTRY" 'END{print $0}'

將記錄分隔符設置為您的模式並打印最后一條記錄。

loadind文件在內存中

 sed -e 'H;$!d' -e 'x;s/.*ENTRY[[:blank:]]*\n//' YourFile

暫無
暫無

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

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