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

时间:2022-10-16 07:28:28

How can I repeat the character - n times in shell? I have read and tried this, but this does not work for -. It throws error invalid option. Below is the exact command that I used:

如何重复角色 - 在shell中重复n次?我已阅读并试过这个,但这不适用于 - 。它抛出错误无效选项。以下是我使用的确切命令:

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

Original posted line: printf '-%0.s' {1..100}

原帖:linef' - %0.s'{1..100}

I also tried escaping - by putting a \ but in that case it repeats \- n times.

我也试过逃避 - 通过放一个\但在那种情况下它重复\ - n次。

6 个解决方案

#1


9  

This throws an error:

这会引发错误:

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

This works fine under bash:

这在bash下工作正常:

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

For other shells, try:

对于其他shell,请尝试:

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

The problem was the printf expects that - starts an option. As is common among Unix/POSIX utilities in this type of situation, -- signals to printf to expect no more options.

问题是printf期望 - 启动一个选项。正如在这种情况下Unix / POSIX实用程序中常见的那样, - 向printf发出信号,期望不再有选择。

#2


4  

John1024's helpful answer provides a generic solution that shows how to disambiguate options from operands for all POSIX-like utilities.

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

In the case at hand, the simplest solution is (works not only in bash, but also in ksh and zsh):

在目前的情况下,最简单的解决方案是(不仅适用于bash,还适用于ksh和zsh):

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

Placing %.0s before the - avoids the issue of an initial - getting mistaken for an option.

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

Slightly optimized:[1]

稍微优化:[1]

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

[1] %.0s is in practice the most portable form (to be fully portable, you must also avoid the brace expansion, {...}).
%.s, the equivalent shorthand form, is supported by bash, ksh, and dash, but not zsh <= v5.2 - even though it is 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."

[1]%。0s实际上是最便携的形式(要完全便携,你还必须避免支撑扩展,{...})。 %.s,等效的简写形式,由bash,ksh和dash支持,但不支持zsh <= v5.2 - 即使它同样符合POSIX:“精度[后面的部分]应采取形式a('。')后跟一个十进制数字字符串;空数字字符串被视为零。“

As a side note: The question originally contained a benign (in Bash) typo that sparked a debate: %0.s instead of %.0s: %0.s should effectively be the same as %.0s, and for that matter, the same as %.s and %0.0s (all effectively request: print a [minimum zero-width] field filled with a zero-length string), but in practice isn't: zsh <= v5.2 doesn't handle %0.s correctly (again, due to the .s part).
Similarly, the GNU printf external-utility implementation (/usr/bin/printf), as of GNU coreutils v8.24, reports an error with %0.s, because it generally doesn't accept a field width of 0 with s: invalid conversion specification - this matters for lesser-known shells that don't provide printf as a builtin. Note that the BSD/OSX implementation does not have this problem.
Both zsh's (<= v5.2) behavior with %.s and GNU /usr/bin/printf's behavior with %0s are deviations from the POSIX spec that smell like bugs.
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 that has yet to be released as of this writing.

作为旁注:这个问题最初包含一个良性(在Bash中)错字引发了争论:%0.s而不是%。0s:%0.s应该与%.0s有效,就此而言,与%.s和%0.0s相同(都有效请求:打印一个填充零长度字符串的[最小零宽度]字段),但实际上不是:zsh <= v5.2不处理%0.s正确(再次,由于.s部分)。类似地,GNU printf外部实用程序实现(/ usr / bin / printf),从GNU coreutils v8.24开始,报告错误为%0.s,因为它通常不接受带有s的字段宽度0:无效的转换规范 - 这对于那些不提供printf作为内置函数的鲜为人知的shell很重要。请注意,BSD / OSX实现没有此问题。带有%.s的zsh(<= v5.2)行为和带有%0s的GNU / usr / bin / printf行为都与POSIX规范的偏差有点像臭虫。这个问题询问了zsh关于%.s的行为,并且该bug已经被确认并报告为通过v5.2之后的提交修复,该提交尚未在撰写本文时发布。

#3


1  

Use a for loop and number range:

使用for循环和数字范围:

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

Or on a single line:

或者在一行上:

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

which outputs ----------.

哪个输出----------。

EDIT: This was before your printf edit.

编辑:这是在你的printf编辑之前。

#4


1  

I would recommend using a traditional for loop, as there is no need to spawn sub-processes or expand 100 arguments:

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

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

It is curious that printf -%s triggers "invalid option" but printf - does not. To perhaps be extra safe, you could do printf %s -.

奇怪的是printf - %s触发“无效选项”但是printf - 却没有。为了安全起见,你可以做printf%s - 。

#5


0  

  1. jot can do it, with no bashisms:

    jot可以做到,没有bashisms:

    jot -s '' -b - 100
    
  2. seq too, but not as well, it needs a tr:

    seq也是,但不是,它需要一个tr:

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

#6


0  

You can also use tput along with printf to accomplish filling the terminal with an exact number of dashes, either drawing the line directly, or writing the line of dashes to a variable (say line) for repeated use, e.g. to write a screen width line of dashes to the variable line, you could do:

您还可以使用tput和printf一起使用精确数量的破折号填充终端,或者直接绘制直线,或者将破折线写入变量(例如线)以供重复使用,例如:要将屏幕宽度的破折号线写入变量行,您可以这样做:

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

and then simply echo "$line" each time you need to draw the line. You can also write it directly to the screen with.

然后在每次需要绘制线时简单地回显“$ line”。您也可以直接将其写入屏幕。

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

(I'm not a huge fan of eval, but this is one use where you are guaranteed the result of the command cannot be harmful).

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

#1


9  

This throws an error:

这会引发错误:

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

This works fine under bash:

这在bash下工作正常:

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

For other shells, try:

对于其他shell,请尝试:

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

The problem was the printf expects that - starts an option. As is common among Unix/POSIX utilities in this type of situation, -- signals to printf to expect no more options.

问题是printf期望 - 启动一个选项。正如在这种情况下Unix / POSIX实用程序中常见的那样, - 向printf发出信号,期望不再有选择。

#2


4  

John1024's helpful answer provides a generic solution that shows how to disambiguate options from operands for all POSIX-like utilities.

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

In the case at hand, the simplest solution is (works not only in bash, but also in ksh and zsh):

在目前的情况下,最简单的解决方案是(不仅适用于bash,还适用于ksh和zsh):

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

Placing %.0s before the - avoids the issue of an initial - getting mistaken for an option.

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

Slightly optimized:[1]

稍微优化:[1]

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

[1] %.0s is in practice the most portable form (to be fully portable, you must also avoid the brace expansion, {...}).
%.s, the equivalent shorthand form, is supported by bash, ksh, and dash, but not zsh <= v5.2 - even though it is 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."

[1]%。0s实际上是最便携的形式(要完全便携,你还必须避免支撑扩展,{...})。 %.s,等效的简写形式,由bash,ksh和dash支持,但不支持zsh <= v5.2 - 即使它同样符合POSIX:“精度[后面的部分]应采取形式a('。')后跟一个十进制数字字符串;空数字字符串被视为零。“

As a side note: The question originally contained a benign (in Bash) typo that sparked a debate: %0.s instead of %.0s: %0.s should effectively be the same as %.0s, and for that matter, the same as %.s and %0.0s (all effectively request: print a [minimum zero-width] field filled with a zero-length string), but in practice isn't: zsh <= v5.2 doesn't handle %0.s correctly (again, due to the .s part).
Similarly, the GNU printf external-utility implementation (/usr/bin/printf), as of GNU coreutils v8.24, reports an error with %0.s, because it generally doesn't accept a field width of 0 with s: invalid conversion specification - this matters for lesser-known shells that don't provide printf as a builtin. Note that the BSD/OSX implementation does not have this problem.
Both zsh's (<= v5.2) behavior with %.s and GNU /usr/bin/printf's behavior with %0s are deviations from the POSIX spec that smell like bugs.
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 that has yet to be released as of this writing.

作为旁注:这个问题最初包含一个良性(在Bash中)错字引发了争论:%0.s而不是%。0s:%0.s应该与%.0s有效,就此而言,与%.s和%0.0s相同(都有效请求:打印一个填充零长度字符串的[最小零宽度]字段),但实际上不是:zsh <= v5.2不处理%0.s正确(再次,由于.s部分)。类似地,GNU printf外部实用程序实现(/ usr / bin / printf),从GNU coreutils v8.24开始,报告错误为%0.s,因为它通常不接受带有s的字段宽度0:无效的转换规范 - 这对于那些不提供printf作为内置函数的鲜为人知的shell很重要。请注意,BSD / OSX实现没有此问题。带有%.s的zsh(<= v5.2)行为和带有%0s的GNU / usr / bin / printf行为都与POSIX规范的偏差有点像臭虫。这个问题询问了zsh关于%.s的行为,并且该bug已经被确认并报告为通过v5.2之后的提交修复,该提交尚未在撰写本文时发布。

#3


1  

Use a for loop and number range:

使用for循环和数字范围:

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

Or on a single line:

或者在一行上:

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

which outputs ----------.

哪个输出----------。

EDIT: This was before your printf edit.

编辑:这是在你的printf编辑之前。

#4


1  

I would recommend using a traditional for loop, as there is no need to spawn sub-processes or expand 100 arguments:

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

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

It is curious that printf -%s triggers "invalid option" but printf - does not. To perhaps be extra safe, you could do printf %s -.

奇怪的是printf - %s触发“无效选项”但是printf - 却没有。为了安全起见,你可以做printf%s - 。

#5


0  

  1. jot can do it, with no bashisms:

    jot可以做到,没有bashisms:

    jot -s '' -b - 100
    
  2. seq too, but not as well, it needs a tr:

    seq也是,但不是,它需要一个tr:

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

#6


0  

You can also use tput along with printf to accomplish filling the terminal with an exact number of dashes, either drawing the line directly, or writing the line of dashes to a variable (say line) for repeated use, e.g. to write a screen width line of dashes to the variable line, you could do:

您还可以使用tput和printf一起使用精确数量的破折号填充终端,或者直接绘制直线,或者将破折线写入变量(例如线)以供重复使用,例如:要将屏幕宽度的破折号线写入变量行,您可以这样做:

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

and then simply echo "$line" each time you need to draw the line. You can also write it directly to the screen with.

然后在每次需要绘制线时简单地回显“$ line”。您也可以直接将其写入屏幕。

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

(I'm not a huge fan of eval, but this is one use where you are guaranteed the result of the command cannot be harmful).

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