簡體   English   中英

如何刪除最后一次出現模式后的所有行?

[英]How to delete all the lines after the last occurence of pattern?

我想刪除模式最后一次出現后的所有行,除了模式本身

文件.txt

honor
apple
redmi
nokia
apple
samsung
lg
htc

file.txt 我想要什么

honor
apple
redmi
nokia
apple

我試過的

sed -i '/apple/q' file.txt

這將刪除第一次出現模式后的所有行 -

honor

幾乎不使用內存的簡單、健壯的 2-pass 方法:

$ awk 'NR==FNR{if (/apple/) hit=NR; next} {print} FNR==hit{exit}' file file
honor
apple
redmi
nokia
apple

如果這執行得不夠快,那么是時候嘗試一些替代方案,看看是否有任何方法可以提高性能。

反轉文件,從模式的第一次出現開始打印所有內容,然后反轉結果:

tac file.txt | sed -n '/apple/,$p' | tac > newfile.txt

您可以找到最后一個匹配項的行號,然后使用它來打印文件的前 N ​​行:

line=$(awk '/apple/ { line=NR } END {print line}')
head -n $line file.txt > newfile.txt

如果您不想像 Barmar 建議的那樣反轉文件,則必須使用較低級別的工具(例如 fseek)反轉讀取文件或讀取它兩次:

sed $(awk '/apple/{a=NR}END{print a+1}' input),\$d input

(請注意,如果該模式未出現在文件中,則不會輸出任何內容。這是您應該擔心的邊緣情況。)

這可能對你有用(GNU sed):

sed '/apple/,$!b;//!H;//{x;//p;x;h};${x;P};d' file

像往常一樣打印不是從apple的第一次出現到文件末尾的任何行。 對於上述范圍內的行,將不包含單詞apple行附加到保持空間 (HS)。 包含單詞apple ,首先交換到 HS 並在那里打印任何單詞apple的行,然后將 HS 替換為包含apple的行。 刪除除最后一行之外的所有行。 在文件末尾打印 HS 的第一行並刪除其余行。

如果吞咽大文件不是問題,請使用:

sed -rz 's/(.*apple[^\n]*).*/\1\n/' file

這使用貪婪來捕獲單詞apple之前並包括單詞的所有行。

這是另一個沒有掃描文件兩次的awk

$ awk 'f       {buf=buf ORS $0} 
       /apple/ {f=1; if(buf)print buf; buf=$0} 
       !f' file

honor
apple
redmi
nokia
apple

如果您不介意將所有內容都保存在內存中,則可以執行以下操作:

$ awk '/^apple$/{last=NR} 
              {lines[NR]=$0}
     END{for(li=1;li<=last;li++) print lines[li]}' file
honor
apple
redmi
nokia
apple

鑒於您正在處理大量輸入,我會使用兩遍coreutils解決方案,例如:

n=$(grep -Fn apple infile | tail -n1 | cut -d: -f1)
[ -n "$n" ] && head -n$n infile > outfile

這使用grep 的固定字符串匹配 ( -F ) 來查找包含蘋果的每一行。 然后使用head提取相關行。

您沒有指定未找到蘋果時會發生什么,因此此解決方案在發生這種情況時不執行任何操作。

暫無
暫無

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

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