2010-05-16 32 views
3

我有一個大的文本文件我想放在我的電子書閱讀器上,但格式化會全部錯誤,因爲所有行在第80列或之前硬包裝與CR/LF,和段落/標頭沒有標記不同,也只有一個單一的CR/LF。僅在某列後用文本文件替換CR/LF

我想要的是用空格替換第75列後的所有CR/LF。這將使大多數段落連續。 (不是一個完美的解決方案,但更好閱讀。)

是否有可能使用正則表達式來做到這一點?最好是一個(linux)perl或sed oneliner,或者一個Notepad ++正則表達式。

回答

2
perl -p -e 's/\s+$//; $_ .= length() <= 75 ? qq{\n} : q{ }' book.txt 

Perl的-p選項意味着:對於每個輸入行,處理和打印。處理代碼隨-e選項提供。在這種情況下:刪除尾隨空白,然後附加換行符或空格,具體取決於行長度。

+0

優秀!既快速,工作得很好,可以理解。 – Olav 2010-05-16 17:17:15

1

這似乎得到相當接近:

sed '/^$/! {:a;N;s/\(.\{75\}[^\n]*\)\n\(.\{75\}\)/\1 \2/;ta}' ebook.txt 

它沒有得到一個段落的最後一行,如果它比75個字符短。

編輯:

這個版本應該做的一切:

sed '/^.\{0,74\}$/ b; :a;N;s/\(.\{75\}[^\n]*\)\n\(.\{75\}\)/\1 \2/;ta; s/\n/ /g' ebook.txt 

編輯2:

如果你想重新包裝在字/句子邊界在不同的寬度(這裏是65,但選擇任何值)以防止文字在頁邊空白處被破壞(或者被截斷的長行):

sed 's/^.\{0,74\}$/&\n/' ebook.txt | fmt -w 65 | sed '/^$;s/\n//}' 

從DOS改變Unix行結尾,只需添加dos2unix到上述任一管道的開頭:

dos2unix < ebook.txt | sed '/^.\{0,74\}$/ b; :a;N;s/\(.\{75\}[^\n]*\)\n\(.\{75\}\)/\1 \2/;ta; s/\n/ /g' 
+0

工作正常,但與perl解決方案相比,並沒有刪除DOS行結尾(我當然可以用'tr'刪除),並且花了很長時間,10.2秒,而perl只有0.08秒。 – Olav 2010-05-16 17:19:48

1

沒有真正回答你的問題,但是你可以使用這個全局連接命令在vim中實現這個結果。在確定線長時,v將選項卡擴展爲空格,這取決於您的源文本可能會有用。

:g/\%>74v$\n/j 
0

的少花哨的辦法是自己與一個LF或CR一條線來代替CR/LF的是apperar,然後刪除所有的CR/LF剩餘。不需要花哨/複雜的東西。

正則表達式1: ^\r\n$ 找到lone cr/lf's。然後替換剩下的那些是微不足道的。請參閱this question以幫助查找np ++中的cr/lf。

+0

啊,但幾乎沒有CR/LF的自己。許多段落只是簡短的一行,我想保留EOL。我選擇了第75列,因爲這會吸引大多數多行包裝段落。我可能必須調整文件到文件的列號以獲得最佳結果。 – Olav 2010-05-16 17:29:22