使用 coreutils 换行和缩进文本

Kon*_*lph 6 make coreutils text-processing text-formatting fold

精简版

我想创建一个多行文本的表格显示,类似于以下内容:

all       Build all targets
document  Create documentation of source files in the subfolders
          `src` and `script`, and write it to `man`
test      Run unit tests
Run Code Online (Sandbox Code Playgroud)

目前,我对此的输入如下所示,但这当然可以更改:

all---Build all targets
document---Create documentation of source files in the subfolders `src` and `script`, and write it to `man`
test---Run unit tests
Run Code Online (Sandbox Code Playgroud)

我已经尝试通过awkwrap/的组合来实现这一点,pr但是虽然换行有效,但缩进却没有。这是我目前的方法:

…
| awk -F '---' "{ printf '%-10s %s\n', $1, $2 }" \
| fold -w $(($COLUMNS - 1)) -s
Run Code Online (Sandbox Code Playgroud)

它生成输出

all       Build all targets
document  Create documentation of source files in the subfolders
`src` and `script`, and write it to `man`
test      Run unit tests
Run Code Online (Sandbox Code Playgroud)

……换句话说,第三行没有按预期缩进。

如何使用给定的换行长度和给定的悬挂缩进宽度格式化文本?— 不改变文本的任何其他内容。奖励:这应该适用于 UTF-8 和转义/控制字符。


背景资料

目标是创建自文档化的 Makefiles。因此,格式化和显示代码的逻辑应该很小,自包含,而不是依赖于单独安装的软件;理想情况下,它应该适用于任何可以执行 Makefile 的系统,因此我对(接近于)coreutils 的限制。

也就是说,我简单地尝试使用解决问题,groff但这很快就变得太复杂了(OS Xgroff和旧版本似乎不支持 UTF-8)。

因此,我尝试解析和格式化的原始字符串如下所示:

## Build all targets
all: test document

## Run unit tests
test:
    ./run-tests .

## create documentation of source files in the subfolders `src` and `script`,
## and write it to `man`
document:
    ${MAKE} -C src document
    ${MAKE} -C script document
Run Code Online (Sandbox Code Playgroud)

目前,这是使用sed忽略多行注释的脚本(有关详细信息,请参阅链接)进行解析,然后再提供给上面发布的格式化代码。

小智 6

在折叠命令之后,将输出通过管道传输到 sed 并用制表符替换行首。您可以使用之前的“tabs”命令来控制缩进:

tabs 5
echo "A very long line that I want to fold on the word boundary and indent as well" | fold -s -w 20  | sed -e "s|^|\t|g"
Run Code Online (Sandbox Code Playgroud)
     一条很长的线
     我想折叠的
     关于这个词
     边界和缩进
     还有


meu*_*euh 5

使用 gnu awk 你可以做一些简单的事情,如下所示:

awk -F '---' '
{ gsub(/.{50,60} /,"&\n           ",$2)
  printf "%-10s %s\n", $1, $2 }'
Run Code Online (Sandbox Code Playgroud)

对于处理长单词的更准确的冗长版本:

awk -F '---' '
{ printf "%-10s ", $1
  n = split($2,x," ")
  len = 11
  for(i=1;i<=n;i++){
   if(len+length(x[i])>=80){printf "\n           "; len = 11}
   printf "%s ",x[i]
   len += 1+length(x[i])
  }
  printf "\n"
}'
Run Code Online (Sandbox Code Playgroud)