3
1

シェルで同じ文字(文字列)をn個繰り返した文字列を作るワンライナー

Last updated at Posted at 2024-07-05

はじめに

シェルのワンライナーでなるべく簡単に同じ文字または同じ文字列を指定した回数繰り返した文字列を作る方法です。

条件

  • 出力の行末にはちゃんと改行をつける
  • POSIX で標準化された機能のみで作る
  • head コマンドは使わない(理由は後述)

基本: printfでn文字のスペース文字列を作る

まずすべてに共通する基本のコードとして n 文字のスペース文字列を作る方法です。printf コマンドの書式の末尾に改行があることに注意してください。

見えないけど10文字のスペースがある
$ printf '%10s\n'
          

スペースだと分かりづらいと思う場合は代わりに 0 を使用する方法もありますが、BusyBox ashでは引数の 0 を省略するとエラーになってしまうため移植性が必要な場合は引数が必要です。その結果、少し長くなってしまいます。

$ printf '%010d\n' 0
0000000000

$ busybox ash -c 'printf "%010d\n"'
ash: invalid number ''
0000000000

変数 n で長さを指定したい場合には次のようにします。

$ printf "%${n}s\n"
          
$ printf '%*s\n' "$n"
          

繰り返しの数をスペースの数で表現することに気がつけば、いろんなものに応用することができます。

同じ文字を繰り返した文字列を作る

同じ文字の繰り返しを作る方法です。tr コマンドを利用します。

$ printf '%10s\n' | tr ' ' =
==========

同じ文字列を繰り返した文字列を作る

同じ文字列(2文字以上の文字)の繰り返しを作る方法です。sed コマンドを利用します。

$ printf '%5s\n' | sed 's/ /=+/g'
=+=+=+=+=+

ちょっとした応用ですが、このようにすれば最初と最後の文字を同じにすることができます。デザインに凝りたい場合に使えるでしょう。

$ printf '%9s\n' | sed -e :a -e 's/ /=/; s/ /+/; ta'
=+=+=+=+=

同じ文字列を縦にn個繰り返す

縦に繰り返す方法です。printf コマンドの書式の末尾に改行がないことに注意してください。

$ printf '%5s' | tr ' ' '\n' | sed 's/^/===/'
===
===
===
===
===

GNU sed や最近の BSD 系の sed に限られますが、次のような書き方もできます。

$ printf '%5s' | sed 's/ /===\n/g'
===
===
===
===
===

なぜhead -n Nを使わないのか?

出力の個数を制限する場合、head コマンドを使うことを思いつくかもしれませんが、head -n N を使用すると SIGPIPE のエラーが(内部的に)発生することがあります。そのため無限に出力して数を制限するよりも、出力の数を制限したほうが良いです。

注意: yesはPOSIXコマンドではありません
$ set -o pipefail
$ yes === | head -n 5
===
===
===
===
===

$ echo $?
141
$ kill -l 141
PIPE

さいごに

他にもいろいろやり方はあると思いますが、シンプルで移植性が高いという点ではこんなところではないかと思います。ブレース展開が POSIX で標準化されると良いんですけどね。

その他の方法(POSIXで標準化されていない拡張機能を使った方法)についてはこちらへ

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1