$ awk 'length > 72' {HOW TO PRINT THE LINEs IN PCS?} msg
即我希望它在 72 个字符后添加\n
并继续,因此最初您可能需要删除所有 single\n
并添加它们。使用其他工具可能会更容易,但让我们尝试一下 awk。
[更新]
威廉姆森提供了正确的答案,但需要一些帮助才能阅读它。我用下面的更简单的示例将问题分成几个部分。
为什么下面的代码
\t
在两种情况下都会打印,gsub
应该替换什么? x 是一个虚拟文件,末尾有一些奇数 0。攻击线
line = $0 \n more = getline \n gsub("\t"," ")
内威廉姆森的回复,line
显然得到整个标准输出,同时more
得到弹出值$0
,对吧?
第 1 部分的代码
$ gawk '{ hallo="tjena\t tjena2"; gsub("\t"," "); }; END {print hallo; gsub("\t", ""); hallo=hallo gsub("\t",""); print hallo }' x
tjena tjena2
tjena tjena20
答案1
不使用 awk
我知道这可能只是您尝试使用 awk 解决的更大问题的一部分,awk
或者只是尝试更好地理解 awk,但如果您真的只想将行长度保持在 72 列,那么有一个很多更好的工具。
该fmt
工具的设计特别考虑到了这一点:
fmt --width=72 filename
fmt
也会努力在合理的地方换行,使输出更容易阅读。有关什么是“合理地点”的info
更多详细信息,请参阅该页面。fmt
答案2
下面是一个 AWK 脚本,它对长行进行换行并重新换行剩余部分以及短行:
awk -v WIDTH=72 '
{
gsub("\t"," ")
$0 = line $0
while (length <= WIDTH) {
line = $0
more = getline
gsub("\t"," ")
if (more)
$0 = line " " $0
else
$0 = line
break
}
while (length >= WIDTH) {
print substr($0,1,WIDTH)
$0 = substr($0,WIDTH+1)
}
line = $0 " "
}
END {
print
}
'
CPAN 上有一个 Perl 脚本,它可以很好地重新格式化文本。它被称为帕拉吉(个人文件)。为了进行连字符,您还需要TeX::Hyphen
。
SWITCHES
--------
The available switches are:
--width=n (or -w=n or -w n)
Line width is n chars long
--left (or -l)
Output is left-justified (default)
--right (or -r)
Output is right-justified
--centered (or -c)
Output is centered
--both (or -b)
Output is both left- and right-justified
--indent=n (or -i=n or -i n)
Leave n spaces for initial indention (defaults to 0)
--newline (or -n)
Insert blank lines between paragraphs
--hyphenate (or -h)
Hyphenate word that doesn't fit on a line
以下是我为支持左边距选项所做的一些更改的差异:
12c12
< my ($indent, $newline);
---
> my ($indent, $margin, $newline);
15a16
> "margin:i" => \$margin,
21a23
> $margin = 0 if (!$margin);
149a152
> print " " x $margin;
187a191,193
> print "--margin=n (or -m=n or -m n) Add a left margin of n ";
> print "spaces\n";
> print " (defaults to 0)\n";
答案3
Awk 是一种图灵完备的语言,而不是一种特别混乱的语言,因此截断行很容易。这是一个简单的命令式版本。
awk -v WIDTH=72 '
{
while (length>WIDTH) {
print substr($0,1,WIDTH);
$0=substr($0,WIDTH+1);
}
print;
}
'
如果你想截断单词之间的行,你可以用 awk 进行编码,但识别单词并不是一件简单的事(因为更多的原因与自然语言有关,而不是算法难度)。许多系统都有一个名为的实用程序fmt
可以做到这一点。
答案4
您询问为什么awk
代码会发出制表符以及零从何而来。
该代码不会
hello
通过调用修改字符串gsub()
。有两个参数,gsub()
作用于$0
。要实际修改hallo
变量,请使用gsub(..., ..., hallo)
.您在字符串末尾得到零,因为
gsub()
返回所做的替换数,并且在某一时刻您将此数字附加到 的值hallo
。
我知道至少有三个专门用于包装和格式化文本段落的实用程序:
fold
,“折叠线过滤器”,即标准 POSIX 实用程序。它只是插入换行符并且不重排文本。fmt
,“简单文本格式化程序”,它也经常默认安装在 Unix 系统上,并且比重fold
排段落更智能。par
,”用于重新格式化段落的过滤器”,它具有检测段落前缀和后缀的附加功能(例如周围有 ASCII 框的文本,或一些源代码中的注释),并且处理缩进和悬挂缩进比fmt
.