Linux 如何在shell中重复破折号(连字符)
如何在shell中重复字符Linux 如何在shell中重复破折号(连字符),linux,bash,shell,repeat,Linux,Bash,Shell,Repeat,如何在shell中重复字符-n次?我已经阅读并尝试过,但这对-不起作用。它抛出错误无效选项。下面是我使用的确切命令: printf '-%.0s' {1..100} 原始发布行:printf'-%0.s'{1..100} 我还尝试通过放置一个\来转义-,但在这种情况下,它会重复\-n次。这会引发一个错误: $ printf '-%.0s' {1..100}; echo "" bash: printf: -%: invalid option printf: usage: printf [-v v
-
n次?我已经阅读并尝试过,但这对-
不起作用。它抛出错误无效选项
。下面是我使用的确切命令:
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 ""
----------------------------------------------------------------------------------------------------
printf '%.0s-' {1..100}
对于其他壳,请尝试:
printf -- '-%.0s' $(seq 100); echo ""
问题在于
printf
期望-
启动一个选项。在这种情况下,Unix/POSIX实用程序中很常见,--
向printf
发送信号,不需要更多选项 对循环和数字范围使用:
for i in {1..10};
do echo "-";
done
或者在一行上:
for i in {1..10};
do echo -n "-";
done
输出<代码>------------
EDIT:这是在您的
printf
编辑之前。我建议使用传统的for
循环,因为不需要生成子进程或扩展100个参数:
N=100
for((i = 0; i < $N; ++i)); do
printf -
done
N=100
对于((i=0;i<$N;++i));做
printf-
完成
奇怪的是,printf-%s
会触发“无效选项”,但printf-
不会。为了更加安全,您可以执行printf%s-
提供了一个通用解决方案,该解决方案显示了如何消除所有类似POSIX的实用程序的操作数选项的歧义
在本例中,最简单的解决方案是(不仅适用于bash
,而且适用于ksh
和zsh
):
将%.0s
放在-
之前可以避免将初始-
误认为选项的问题
略微优化:[1]
[1]
%.0s
实际上是最可移植的形式(要完全可移植,还必须避免大括号扩展,{…}
)。%.s
是一种等效的速记形式,受bash
、ksh
和dash
支持,但不受zsh
jot
可以做到这一点,不带任何羞耻感:
seq也一样,但也不一样,它需要一个tr
:
seq -s- 100 | tr -d '[0-9]'
您还可以使用
tput
和printf
来完成用确切数量的破折号填充终端,或者直接画线,或者将破折号线写入变量(例如line
),以便重复使用,例如,将屏幕宽度的破折号线写入变量line
,你可以做:
$ eval printf -v line '%.0s-' {1..$(tput cols)}
然后每次需要画线时,只需回显“$line”
。您还可以使用将其直接写入屏幕
$ eval printf '%.0s-' {1..$(tput cols)}
(我不是
eval
的超级粉丝,但这是一个可以保证命令结果不会有害的用途)。这是我多年来的目标。。。但对AIX不友好。更改最后一个字符以更改组成该行的重复字符
printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' _
+1.这个解决方案值得记住,因为它不是printf特有的;许多实用程序支持将
--
作为一个特殊标志,表示“在这一点之后没有更多选项”。不仅仅是Linux实用程序,它是POSIX指定的实用程序约定。参见@CharlesDuffy Very good中的准则10。更新了答案以提及POSIX。我检查了,因为它不接受任何选项,所以它没有提到接受--
。事实上。这就是说,POSIX的实用程序指南部分指出,与指南的偏差将在实用程序的单独文档的选项部分进行描述。echo-n
显然是非POSIX指定的行为。如果你想随身携带,你可能会远离它。请参阅:“如果第一个操作数为-n,或者如果任何操作数包含反斜杠(“\”)字符,则结果由实现定义”感谢提示!出于这个原因,printf
是更好的选择吗?是的。(请参阅前面链接中的应用程序使用部分)-
是一个完全有效的参数,通常用于根据上下文引用stdin或stdout,而-x
设置一个选项标志。在算术求值中不需要$
:for((i=0;iprintf'.s-'{1..100}
不涉及子shell,因为大括号扩展是一个shell功能,printf
是一个Bash内置函数。因此,将大括号扩展与内置函数printf
相结合不受最大命令行长度的限制,但您是对的,在重复次数较多的情况下,有一些替代方法更快,尤其是更快内存效率高(但shell循环不是用于大量重复计数的正确工具)-参见。@mklement0确实,我在考虑涉及子进程批评的perl
、tr
、head
等解决方案。如果printf
不是内置的,那么我发布的解决方案将产生100个进程!是的,我对使用{1..N}
的批评是它需要O(N)空格。事实上,{1..N}
实际上需要Ω(N log N)空格,因为每个参数的大小都是以对数方式增加的……标题是“破折号”,但它的标签是“bash”。你指的是哪一个?@Kusalananda:OP指的是破折号字符(-
,ASCII/Unicode码点0x2d
)。(严格来说,字符的名称是连字符,但实际上这两个名称可以互换使用。)@mklement0啊。我这方面有严重的误解。我最近读了太多语言严重混乱的问题……因为jot
不是POSIX指定的工具,它可以说和bash一样不可移植。同样的批评也适用于seq
@CharlesDuffy,没错……但是OP中没有POSIX标记。如果,正如你所说的那样注释,zsh和GNU printf(至少)失败(当时
$ eval printf '%.0s-' {1..$(tput cols)}
printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' _