替換大檔案中包含換行符的字串

替換大檔案中包含換行符的字串

有人知道基於非行的工具可以以某種節省記憶體的方式「二進位」搜尋/替換字串嗎?這個問題也。

我有一個 +2GB 的文本文件,我想對其進行類似於以下操作的處理:

sed -e 's/>\n/>/g'

這意味著,我想刪除 a 之後出現的所有換行符>,但不刪除其他地方出現的換行符,這樣就排除了tr -d.

這個命令(我從類似問題的答案) 失敗並顯示couldn't re-allocate memory

sed --unbuffered ':a;N;$!ba;s/>\n/>/g'

那麼,除了C語言之外,還有其他方法嗎?我討厭 Perl,但我願意在這種情況下破例:-)

我不確定數據中沒有出現任何字符,因此\n如果可能的話,我想避免臨時替換為另一個字符。

大家有什麼好主意嗎?

答案1

這在 Perl 中確實是微不足道的,你不應該討厭它!

perl -i.bak -pe 's/>\n/>/' file

解釋

  • -i:就地編輯文件,並建立原始文件的備份,稱為file.bak.如果您不需要備份,只需使用perl -i -pe即可。
  • -pe:逐行讀取輸入文件,並在應用給定的腳本後列印每一行-e
  • s/>\n/>/: 替換,就像sed.

這是一種awk方法:

awk  '{if(/>$/){printf "%s",$0}else{print}}' file2 

答案2

一個perl辦法:

$ perl -pe 's/(?<=>)\n//'

說明

  • s///用於字串替換。
  • (?<=>)是lookbehind模式。
  • \n匹配換行符。

整個模式意味著刪除>之前的所有換行符。

答案3

這個怎麼樣:

sed ':loop
  />$/ { N
    s/\n//
    b loop
  }' file

對於 GNU sed,您也可以嘗試根據問題新增-u( ) 選項。 --unbufferedGNU sed 也很高興將此作為一個簡單的單行程式碼:

sed ':loop />$/ { N; s/\n//; b loop }' file

答案4

sed不提供在沒有最終換行符的情況下發出輸出的方法。您使用的方法N從根本上有效,但在記憶體中儲存不完整的行,因此如果行變得太長,則可能會失敗(sed 實作通常不設計用於處理極長的行)。

您可以使用 awk 代替。

awk '{if (/<$/) printf "%s", $0; else print}'

另一種方法是使用tr「無聊」的頻繁出現的字元來交換換行符。空格在這裡可能會起作用 - 選擇一個往往出現在資料中的每一行或至少大部分行上的字元。

tr ' \n' '\n ' | sed 's/> />/g' | tr '\n ' ' \n'

相關內容