我正在研究一种简单的方法,强制文件中的空白处在边距/字符限制下进行硬换行,即任何行都不能超过 n 个字符,并且换行符位于单词之间。我在 BBEdit 中工作:
Find: (.{1,26})(\h+\R?|\R)
Replace: \1\n
但我无法让它在 sed (MacOS 12 zsh) 中工作
我最接近的是:
sed -i .bak -E 's#(.{1,26})(\h+\R?|\R)#\1\n#g' file.txt
但它会在单词中间进行换行,并且完全遗漏了一些行,使它们远远超出了限制(在本例中为 26 行)。我已经在 sed 命令中尝试过 \s \t 和 \n ,但没有任何效果。是否有我错过的不同语法或者不同的命令更合适?谢谢。
答案1
怎么样:
sed -r 's/(.{1,26}) /\1\n/g' file.txt
我不得不承认我不明白你的意思(\h+\R?|\R)
——也许有一些复杂的事情正在发生。
答案2
\h
并且\R
不是标准的。我认为\h
是[[:blank:]]
,并且\R
被描述为 (?>\x0D\x0A|\v)
,它与 Windows CRLF 换行符或任何垂直空格匹配。除非有一些 Unicode 差异,或者我错过了其他东西。
您几乎可以直接使用 Perl 来实现这一点:
$ cat file.txt
Perl is a weird programming language that has taken some influences from
sed, among other things.
$ perl -pe 's/(.{1,25})([[:blank:]]+\n?|\n)/$1\n/g' < file.txt
Perl is a weird
programming language that
has taken some influences
from
sed, among other things.
或者使用 sed,您需要将\h
and替换\R
为例如[[:blank:]]
and \n
。尽管您可能需要 GNU sed 才能正常\n
工作。另外,要让 sed 在缓冲区中包含尾随换行符以便可以进行匹配,您需要 GNU sed 的-z
选项来使其考虑以 NUL 分隔的“行”,从而形成\n
常规字符。您还可以将模式修改为具有(...|\n|$)
,但随后您将在文件中已存在的任何换行符之前添加额外的换行符。
$ sed -z -E 's#(.{1,40})([[:blank:]]+\n?|\n)#\1\n#g' < file.txt
Perl is a weird programming language
that has taken some influences from
sed,
among other things.
尽管如上所示,正则表达式不会删除任何现有的换行符,如上所示。