以下awk
代码在第 72 列处换行:
awk -v maxLen=72 '
{
out = sep = ""
for ( i=1; i<=NF; i++ ) {
nextOut = out sep $i
if ( length(nextOut) > maxLen ) {
print out
out = $i
}
else {
out = nextOut
sep = FS
}
}
print out
}
' "$1" > "$2"
input.txt
:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do euismo tempor incididunt ut labore et dolore magna aliqua.
output.txt
:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do euismo
tempor incididunt ut labore et dolore magna aliqua.
但问题是它只适用于 ASCII 文本。如果文本使用西里尔字母,行会变得短得多。
input.txt
:
Лорем ипсум долор сит амет, консектетур адиписцинг элит, сед до еусимо темпор инцидидант ют лаборе эт долоре магна аликуа.
output.txt
:
Лорем ипсум долор сит амет, консектетур
адиписцинг элит, сед до еусимо темпор
инцидидант ют лаборе эт долоре магна
аликуа.
如果我理解正确的话,这是因为awk
计算的是字节数,而不是字符数。但是如何解决这个问题呢?
技术说明:我使用的awk
是随 macOS 提供的。
正如您所说,您的版本
awk
似乎计算的是字节数,而不是字符数。要解决此问题,请使用字符感知实现,例如GNU Awk或The One True Awk (已针对AWK 编程语言第二版进行了更新)。GNU Awk 生成
使用 UTF-8 语言环境的示例输入。
在 macOS 上,这两个实现都可以使用 Homebrew 安装,尽管一次只能安装一个(它们相互冲突):
安装 GNU Awk,而
安装唯一真正的 Awk。
虽然它没有回答您的确切问题,但对于这种特定情况,您可以考虑使用
fold
具有此确切目的的命令(“换行以适合指定的宽度”)。 在你的情况下:默认情况下,它计算列(=字符)而不是字节。
如果需要支持非 ASCII 字符和非英语文本,还需要考虑双宽或零宽度(如组合标记)字符,以及 Unicode 中可以找到的大量空格字符,其中一些字符不能换行,如不间断空格。
在这里,我将使用
perl
及其内置Unicode::LineBreak
模块。例子:
如果输入包含 TAB 字符,您可能需要将输入提供给
expand
first(指定制表符结束的位置,如果不是 8 列间隔的话)。请注意,并非所有expand
实现都支持零宽度或双宽度字符,尽管 IIRC BSD 的实现通常都支持。另请参见col -b
输入是否包含退格字符(有时用于粗体或下划线)。