有人知道基於非行的工具可以以某種節省記憶體的方式「二進位」搜尋/替換字串嗎?看這個問題也。
我有一個 +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
( ) 選項。 --unbuffered
GNU 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'