如何在 shell 中重复破折号(连字符)

How to repeat a dash (hyphen) in shell

如何在 shell 中重复字符 - n 次?我已阅读并尝试 this,但这不适用于 -。它抛出错误 invalid option。下面是我使用的确切命令:

printf '-%.0s' {1..100}

原贴行:printf '-%0.s' {1..100}

我也尝试通过放置 \ 来转义 - 但在那种情况下它会重复 \- n 次。

这会引发错误:

$ printf '-%.0s' {1..100}; echo ""
bash: printf: -%: invalid option
printf: usage: printf [-v var] format [arguments]

这在 bash 下工作正常:

$ printf -- '-%.0s' {1..100}; echo ""
----------------------------------------------------------------------------------------------------

对于其他 shell,尝试:

printf -- '-%.0s' $(seq 100); echo ""

问题是 printf 期望 - 启动一个选项。在这种情况下,Unix/POSIX 实用程序很常见,--printf 发出信号,希望没有更多选项。

使用 for 循环和数字范围:

for i in {1..10}; 
    do echo "-"; 
done

或单行:

for i in {1..10}; 
    do echo -n "-"; 
done

输出 ----------.

编辑:这是在您 printf 编辑之前。

我建议使用传统的 for 循环,因为不需要生成子进程或扩展 100 个参数:

N=100
for((i = 0; i < $N; ++i)); do
  printf -
done

奇怪的是 printf -%s 触发了 "invalid option" 而 printf - 却没有。为了更加安全,您可以 printf %s -.

提供了一个通用解决方案,展示了如何为 所有 POSIX 类实用程序的操作数消除选项歧义。

在手头的情况下,最简单的解决方案是(不仅适用于 bash,而且适用于 kshzsh):

printf '%.0s-' {1..100}

%.0s 放在 之前 - 避免了初始 - 被误认为选项的问题。

略微优化:[1]

printf '%.s-' {1..100}

[1] %.0s 在实践中最便携的 形式 (完全便携,您还必须避免大括号扩展,{...}).
%.s,等效的 shorthand 形式,bashkshdash 支持], 但 不是 zsh <= v5.2 - 即使它是 equally POSIX-compliant : "The precision [the part after .] shall take the form of a ( '.' ) followed by a decimal digit string; a null digit string is treated as zero."

作为 旁注 :该问题最初包含一个良性的(在 Bash 中)打字错误,引发了一场辩论:%0.s而不是 %.0s%0.s 应该 实际上与 %.0s 相同,就此而言,与 %.s%0.0s(所有有效请求:打印一个用零长度字符串填充的[最小零宽度]字段),但实际上不是zsh < = v5.2 没有正确处理 %0.s(同样,由于 .s 部分)。
同样,从 GNU coreutils v8.24 开始,GNUprintfexternal-utility 实现(/usr/bin/printf)报告错误 %0.s,因为它通常不接受 0s 的字段宽度:invalid conversion specification - 这很重要对于不提供 printf 作为 内置 的鲜为人知的 shell。请注意,BSD/OSX 实现没有此问题。
zsh (<= v5.2) 与 %.s 的行为和 GNU /usr/bin/printf%0s 的行为都是与 POSIX 规范的偏差像虫子。
This question asks about zsh's behavior regarding %.s, and the bug has since been confirmed and reported as fixed via a post-v5.2 commit 在撰写本文时尚未发布。

  1. jot可以做到,没有bash主义:

    jot -s '' -b - 100
    
  2. seq 也是,但不是那么好,它需要一个 tr:

    seq -s- 100 | tr -d '[0-9]'
    

您还可以使用 tputprintf 来完成用精确数量的破折号填充终端,直接绘制线,或将破折号线写入变量(比如line) 重复使用,例如将屏幕宽度的虚线写入变量 line,您可以这样做:

$ eval printf -v line '%.0s-' {1..$(tput cols)}

然后每次需要画线时只需 echo "$line"。你也可以直接把它写到屏幕上。

$ eval printf '%.0s-' {1..$(tput cols)}

(我不是 eval 的忠实粉丝,但这是一种保证命令结果不会有害的用途)。

这多年来一直是我的目标...虽然对 AIX 不友好。更改最后一个字符以更改构成行的重复字符

printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' _