文字列をn回繰り返すLinuxコマンド


71

入力文字列のn倍の文字列を出力できる組み込みLinuxコマンドはありますか??


1
「ビルトインlinuxコマンド」とは、シェルコマンドを意味すると仮定します。使用しているシェルについては言及していないので、bashであると仮定します。これを確認するには、コマンドラインで「echo $ SHELL」と入力すると、「/ bin / bash」に似たものが返されます。そうでない場合は、回答を編集して表示内容を指定する必要があります。乾杯:)
エイドリアンペトレスク

7
質問に「bash」というタグを付けました。それで十分だと思った。
GetFree

回答:


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

3
これがどのように機能するか説明できますか?printfコマンドはC / C ++のものと同じなので理解しています。しかし、{1..5}がどのように展開されるか、そしてそれが "%.0s"部分とどのように連動するかを理解していません。
GetFree 09

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
(純粋に理論的な観点から、これはおそらく外部プロセスではなく単一のシェルプリミティブを使用するため、おそらく最速のソリューションです。実際には、bashスクリプトのパフォーマンスは重要ではありません。 )
エイドリアンペトレスク

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 14年

4
はいの解決策はかなりきちんとしています
-piggybox

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ではありません
チロSantilli新疆改造中心法轮功六四事件

データをprintfの形式指定子に混在させないでください。データにフォーマット文字列が含まれている場合はどうなりますか?これは、「精度」(長さ)を動的に指定する正しい方法printf '%*s' "$N"です。
デニスウィリアムソン

13

すでに述べたいくつかの良い方法。古き良き時代を忘れることはできませんseq

[john @ awesome] $ 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シェルは、ほとんどの人が考えるよりも強力です:)


これは完全にシェル内部であるため、私の票を得ます。フォークは必要ありません。
esm

2
フォークとは何ですか?元の答えには何も必要ありません。「type printf」の出力は「printf is a shell builtin」であるため、元のbashプロセス内で実行されます。
CodeGnome

これはこれまで(唯一のものであるyesprintffor i in {1..5})場合にnゼロであり、それは空の文字列を返すによる比較するための数学的表記することも1の状態を存在せず、それは1だけオフセットしていることは容易である(変化させることにより、例えば、<=への<
Mehrad Mahmoudian

10

トリックを使用できます。空の変数をエコーし​​ても何も出力されません。だからあなたは書くことができます:

echo word$wojek{1..100}

場合$wojek1 $wojek2... $wojek100存在しない変数であり、あなたの言葉は、何かせずに100回繰り返されます。


1
それはいいハックですが、それでも私はそれを愛し、それを使わざるを得ません。
-16807

大好きです!たぶん、$_代わりに使用$wojekすると、意図がより明確になります。
ミハイトドール

7

繰り返しnn-1カンマを次の間に入れて{}ください:

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

最初のエコーの後に「helloworld」を2回繰り返します。


5
いいですがn、変数から取得したい場合はどうすればいいですか?
-GetFree

1
各「helloworld」の後に余分なスペースが追加されます
PADYMKO

これにより、文字列に改行を入れることもできません(つまり、独自の行でhelloworldを取得します)
TankorSmash

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

結果

ハローハローハローハロー

これをawkなしで使用します:while((c ++ <5)); printf 'hello'; 行って
EMF

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の間を移植するようで、それが嬉しいです。

nJoy!


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 seqでのみ機能するという情報が欠落している人のために、ここに情報を含めます。
パレック

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

出力

ten ten ten ten ten ten ten ten ten ten

たぶんもっと冗長な例:declare c = '-----'; c = $ {c // $ {c:0:1} / $ c}; echo $ c#「-」を25回出力します。
スティーブンニエ

2

x繰り返しの間に改行を自動的に取得しないPerlの演算子のようなものが必要だと仮定します。

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

bashでfor記述できないため、ループを明示的に使用しました{1..$n}。変数置換の前にブレース展開が行われます。


2

正確にはLinuxに組み込まれていませんが、Pythonがインストールされている場合。

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

または、コメンターが示唆したように、1行で:

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

4
シェルスクリプトなどに簡単に統合できないため、それほど便利ではありません。また、シェル自体でこれを行うには約10億の方法があるため、大きな銃(Pythonなど)を引き出す理由はほとんどありません。 。
エイドリアンペトレスク

7
私はあなたの2番目の点に同意しますが、拳ではありません...シェルスクリプトに統合するのは簡単です:python -c 'print "This is a test。\ n" * 10'
larsks

私はこのソリューションの可読性が好きで、私には十分な理由があります。;)
エリアス


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.