Linux命令将字符串重复n次


71

有没有内置的Linux命令允许输出一个字符串,该字符串是输入字符串的n倍?


1
通过“内置linux命令”,我假设您的意思是shell命令,并且由于您没有提及正在使用的shell,所以我假设它是bash。您可以通过在命令行中键入“ echo $ SHELL”来进行检查,并且应该返回类似于“ / bin / bash”的信息。如果不这样做,则应编辑答案以指定显示的内容。干杯:)
Adrian Petrescu,2009年

7
我用“ bash”标记了这个问题。我以为就足够了。
GetFree

Answers:


75
adrian@Fourier:~$ printf 'HelloWorld\n%.0s' {1..5}
HelloWorld
HelloWorld
HelloWorld
HelloWorld
HelloWorld
adrian@Fourier:~$

3
您能解释一下这是如何工作的吗?我了解printf命令,因为它与C / C ++中的命令相同。但是我不理解{1..5}是如何扩展的,以及它如何与“%.0s”部分结合使用。
GetFree

4
有点黑:)尝试运行“ printf'HelloWorld%d \ n'1 2 3 4 5”,它可能会为您点击。%.0s标志的作用是不执行任何操作,只是在那里接受参数。然后,如果bash获得的参数多于格式说明符,则它将简单地打印出多个副本,并根据需要获取尽可能多的副本。这样您就可以得到效果。“ printf'HelloWorld%d%d \ n'1 2 3 4 5 6”的输出可能使它更加清晰。希望这可以帮助!
阿德里安·佩特雷斯库

我懂了。允许重复的是printf的特殊行为
GetFree

1
(我应该注意,从纯粹的理论角度来看,这可能是最快的解决方案,因为它使用单个shell原语-而不是任何外部进程。实际上,让我们面对现实,bash脚本的性能并不重要: )
Adrian Petrescu,2009年

1
什么具体到printf是,它会反复施加过参数格式字符串,“循环”是免费的。所谓“多余”,是指争论点多于%占位符。
丹尼斯·威廉姆森

69

这是一种可移植的老式方法:

yes "HelloWorld" | head -n 10

这是使用括号扩展的Adrian Petrescu回答的更常规版本:

for i in {1..5}
do
    echo "HelloWorld"
done

这等效于:

for i in 1 2 3 4 5

这是派克答案的更为简洁和动态的版本:

printf -v spaces '%*s' 10 ''; printf '%s\n' ${spaces// /ten}

使用yes命令时如何摆脱换行?
GetFree

3
一种方法是通过管道进行传递sed -n 'H;${x;s/\n//gp}'sed -n ':t;${s/\n//gp};N;bt'另一种方法是echo $(yes "HelloWorld" | head -n 10)在字符串的每个副本之间添加一个空格。还有另一种方法是通过管道传输它,tr -d '\n'这也消除了最终的换行符。
丹尼斯·威廉姆森

2
就像bash外壳中的Haskell:Hashell?
wchargin 2014年

4
是的解决方案非常简洁
储钱罐

yes解决方案正是我需要的,因为我想复制一条命令(其输出会波动)。因此:yes "$(my-command)" | head -n 2
arnsholt

14

可以将其参数化,并且不需要临时变量FWIW:

printf "%${N}s" | sed 's/ /blah/g'

或者,如果$Nbash数组的大小是:

echo ${ARR[@]/*/blah}

3
这是最短的POSIX 7解决方案至今,因为我已经看到seqyes{1..5}没有POSIX 7
西罗桑蒂利新疆改造中心法轮功六四事件

您不应该将数据混入printf的格式说明符中。如果数据包含格式字符串怎么办?这是动态指定“精度”(长度)的正确方法:printf '%*s' "$N"-习惯将格式字符串用单引号引起来,以防止变量在那里扩展。
丹尼斯·威廉姆森

13

已经提到了很多好的方法。seq虽然不能忘记好老:

[john @ awesome] $ s for i in`seq 5`; 做回声“嗨”;完成
你好
你好
你好
你好
你好

这个实际上尊重一个零,将其视为零!(这{i..j}招绝不会返回空范围。)
JellicleCat

10

也许另一种更通用和对您有用的方式:

adrian@Fourier:~$ n=5
adrian@Fourier:~$ for (( c=1; c<=n; c++)) ; do echo "HelloWorld" ; done
HelloWorld
HelloWorld
HelloWorld
HelloWorld
HelloWorld
adrian@Fourier:~$ 

bash shell比大多数人认为的强大:)


这是我的投票,因为它完全是shell内部的。无需分叉。
esm

2
您指的是什么分叉?原始答案不需要任何内容​​。“ printf类型”的输出是“ printf是内置的shell”,因此在原始bash进程中运行。
CodeGnome 2012年

这是唯一的一个迄今(yesprintffor i in {1..5}),如果n是零,则返回空字符串不存在的1。此外状态由于用于比较的数学符号,很容易通过已1偏移量(例如通过改变<=<
Mehrad Mahmoudian

10

您可以使用技巧。回显一个空变量不会打印任何内容。所以你可以这样写:

echo word$wojek{1..100}

如果$wojek1 $wojek2... $wojek100是不存在的变量,则您的单词会重复100次,而无需其他任何操作。


1
这是一个丑陋的丑陋的hack,但是我忍不住喜欢它并使用它。
7807年

爱它!也许使用$_而不是$wojek使意图更清晰。
Mihai Todor

7

重复n几次,只需n-1在之间加上逗号{}

$ echo 'helloworld'{,,}
helloworld helloworld helloworld

在第一个回声之后重复两次“ helloworld”。


5
很好,但是如果我想n从变量中得到怎么办?
GetFree 2012年

1
它在每个“ helloworld”之后增加了一个额外的空间
PADYMKO

这似乎也不允许您在字符串中添加换行符(即在自己的行上添加helloworld)
TankorSmash

5
awk 'BEGIN {while (c++<4) printf "Hello"}'

结果

你好你好你好你好

不使用awk使用它:while((c ++ <5)); 做printf'hello'; 完成
电动势

4

我在yes解决方案中遇到过管道破裂的警告,因此这是另一个不错的选择:

$ seq 4 | sed "c foo"
foo
foo
foo
foo

3

根据@pike暗示的内容

对于字符串中的每个字符,回显字符串

echo ${target//?/$replace}

=字符下划线的标题示例

export heading='ABCDEF'; 
export replace='='; 
echo -e "${heading}\n${heading//?/$replace}"

将输出

ABCDEF
======

这似乎是在Linux和OS X之间移植的,这让我很高兴。

欢乐!


3

如果您使用的是BSD,则可以使用seq

$ seq -f "Hello, world" 5
Hello, world
Hello, world
Hello, world
Hello, world
Hello, world

1
在中seq (GNU coreutils) 8.25,这给出seq: format 'Hello, world' has no % directive,强制存在格式指令。GNU coreutils用于许多Linux发行版和Cygwin。对于那些缺少仅在BSD序列中起作用的信息的人,请在此处包括信息。
Palec

2
line="==========================="
line=${line:0:10}
${line//"="/"ten "}

输出

ten ten ten ten ten ten ten ten ten ten

也许是一个更冗长的例子:声明c ='-----'; c = $ {c // $ {c:0:1} / $ c}; echo $ c#打印“-” 25次。
Stephen Niedzielski

2

假设您想要类似Perl的x运算符,那么您不会在重复之间自动获得换行符:

x() {
  # usage: x string num
  for i in $(seq 1 $2); do printf "%s" "$1"; done
  # print a newline only if the string does not end in a newline
  [[ "$1" == "${1%$'\n'}" ]] && echo ""
}

x Hi 10  # ==> HiHiHiHiHiHiHiHiHiHi

x $'Hello World!\n' 3

我明确使用了for循环,因为您不能用{1..$n}bash 编写:大括号扩展是在变量替换之前完成的。


2

并非完全内置到linux中,但是如果您安装了python。

python
>>>var = "string"
>>>var*n

或者在一行中,如评论者所建议的那样:

python -c 'print "This is a test.\n" * 10'

4
并不是那么有用,因为它不能轻松地集成到Shell脚本等中。而且由于Shell本身有十亿种方法可以执行此操作,因此我几乎没有理由为此而出手。
阿德里安·佩特雷斯库

7
我同意你的第二个问题,但不是拳头......很容易地集成到一个shell脚本:蟒蛇-c“打印‘这是一个测试\ n’* 10”
larsks

我喜欢此解决方案的可读性,这对我来说是充分的理由。;)
elias 2015年


1

试试这个:

echo $(for i in $(seq 1 100); do printf "-"; done)

将创建(一百个破折号):


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.