シェルスクリプトでスペースを印刷する方法

シェルスクリプトでスペースを印刷する方法

固定幅コンソール出力にパディングを提供するために、特定の数の「空白」文字を印刷するシェル関数を実装しようとしています。

#!/bin/bash

function printWhiteSpaces
{
  local i="122"
  local len="$1"
  local whitespace=' '
  local k=`expr $i - $len`
  while [ $k -gt 0 ]
  do
    echo "${whitespace}"
    ((k--))
  done
}

上記の関数は、パラメータを「何かの長さ」として受け入れ、次に所望のフィールド幅122とパラメータとの間の差をもたらす$1。印刷したいそれ空白文字が多いです。

なぜ空白が印刷されないのですか?上記の機能に対する解決方法や改善事項がある方は共有してください。特に、空白文字を連結して印刷するこの関数を書くより良い方法があるかどうか疑問に思います。

これまでのソリューション:

#!/bin/bash

function printWhiteSpaces
{
  local i="122"
  local len="$1"
  local k=`expr $i - $len`
  local whitespace=' '
  while [ $k -gt 0 ]
  do
    echo -n "${whitespace}"
    ((k--))
  done
}

答え1

あなたの目標が固定された空白の塗りつぶしフィールドの長さで文字列変数を印刷することであれば、次の関数を使用することをお勧めprintfしますbash

printf "%122s" "$myvar"

$myvar内容は左側に印刷され、合計122文字を埋めるのに十分なスペースが残ります。

次の簡単なテストを試してください(読みやすくするために、フィールドの幅は20と見なされます)。

~> myVar="Hi, there!"; printf '%20s\n' "$myVar"
          Hi, there!
~> myVar="Bye!"; printf '%20s\n' "$myVar"
                Bye!

echo改行文字が最後に暗黙的に印刷されるため、元の方法は機能しません。

シェルループでのみ使用するには、改行を抑制するためにechoそれを呼び出す必要がありますecho -n

~> myVar="Bye!"; l=${#myVar}; for ((i=20;i>l;i--)); do echo -n ' '; done; echo "$myVar"
                Bye!

答え2

このスクリプト(bashとshでテスト済み):

#!/bin/sh

function printWhiteSpaces() {
  local i="122"
  local len="$1"
  local k=`expr $i - $len`
  local whitespace='                                                                                                                                                                  '
  echo "${whitespace:0:$k}" test
}

printWhiteSpaces 100
printWhiteSpaces 110
printWhiteSpaces 120

私はあなたが望むものだと思う次のような出力を生成します。

                       test
             test
   test

(これはMacで行われましたが、これが影響を与えるかどうか疑問です。)

答え3

関数内でコマンドラインを操作できます。したがって、$ kパラメータ(すべて空白)を使用して新しいコマンドラインを作成します。構成が完了した後に$*コマンドラインを二重引用符で囲むと、IFSの最初のchar(=空白)区切りパラメータが提供され、すべてのパラメータが空であるため、空白のみがたくさん表示されます。

function printWhitespaces
{
  local i="122"
  local len="$1"
  local whitespace=' '
  local k=`expr $i - $len`
  set -- ""
  while [ "$#" -le "$k" ]
  do
    set -- "$@" "$1"
  done
  echo "$*"
}

$k変数をすでに計算している場合は、他の方法は次のとおりです。

printf '%*s\n' "$k" ""

関連情報