変数が空であるか、スペースのみが含まれているかどうかをテストするにはどうすればよいですか?

次のbash構文は、paramが空でないかどうかを確認します。

 [[ ! -z $param ]] 

例:

param="" [[ ! -z $param ]] && echo "I am not zero" 

出力なしで問題ありません。

ただし、paramは、1つ(または複数)のスペース文字を除いて空です。大文字と小文字は異なります:

param=" " # one space [[ ! -z $param ]] && echo "I am not zero" 

「私は違いますゼロ」が出力されます。

空白文字のみを含む変数を空と見なすようにテストを変更するにはどうすればよいですか?

コメント

  • man testから:-z STRING - the length of STRING is zero$paramのすべてのスペースを削除する場合は、 ${param// /}
  • WOW を使用する単純なtrim()関数が組み込まれていません* nixはありますか?非常に単純なことを実現するためのさまざまなハックがあります…
  • @ADTC $(sed ‘ s / ^ \ s + | \ s + $ // g ‘ < < < $ string)は私には十分単純に思えます。車輪の再発明を行う理由
  • 光沢がある可能性があるため
  • [[ ! -z $param ]]test ! -z $param

回答

まず、 -zテストは明示的に次の目的で使用されます。

文字列の長さがゼロ

つまり、スペースのみを含む文字列はすべきではありませんは、長さがゼロ以外であるため、-zの下でtrueになります。

必要なのは、

パターン置換パラメータの拡張:

[[ -z "${param// }" ]] 

これにより、param変数であり、パターン(単一のスペース)のすべての一致を何も置き換えないため、スペースのみを含む文字列はに展開されます。空の文字列。


その仕組みの要点は、${var/pattern/string} patternの最初の最長一致をstringに置き換えます。 pattern/で始まる場合(上記のとおり)、すべての一致が置き換えられます。置換が空であるため、最後の/stringの値を省略できます:

$ {parameter / pattern / string}

pattern は、ファイル名の展開と同じようにパターンを生成するように展開されます。 パラメータが展開され、その値に対するパターンの最長一致が文字列に置き換えられます。 pattern が「/」で始まる場合、 pattern のすべての一致は string に置き換えられます。通常、最初の一致のみが置き換えられます。 … string がnullの場合、 pattern の一致は削除され、/に続く pattern は省略できます。

その後、すべてのスペースを削除する${param// }になります。

ただし注意してくださいksh(元の場所)、zshおよびbashに存在し、その構文はPOSIXであり、shスクリプトでは使用しないでください。

コメント

  • use sed彼らが言った…ただecho彼らが言った変数…
  • うーん。 ${var/pattern/string}の場合は、’スラッシュの間にスペースを入れて[[ -z ${param/ /} ]]にする必要があります。パターンになり、その後に文字列になりますか?
  • @JesseChisholm “置換が空であるため、最後の/と文字列の値を省略できます”; ” string がnullの場合、 pattern の一致は削除され、/に続く pattern は次のようになります。 ”
  • @MichaelHomer答え[[ -z "${param// }" ]]は確かにpatternは空で、replacement stringは単一のスペースです。 AH!今は見えますif pattern begins with a slashその部分を見逃しました。したがって、パターンは/ であり、文字列は省略されているため、空です。ありがとう。
  • bash注:set -o nounset(set -u)で実行していて、paramが(nullまたはスペースで埋められているのではなく)設定されていない場合、これにより非バインド変数エラーが生成されます。 (set + u; …..)はこのテストを免除します。

回答

簡単な方法文字列に許可されたセットの文字のみが含まれていることを確認することは、許可されていない文字の存在をテストすることです。したがって、文字列にスペースのみが含まれているかどうかをテストする代わりに、文字列にスペース以外の文字が含まれているかどうかをテストします。 bash、ksh、またはzshの場合:

if [[ $param = *[!\ ]* ]]; then echo "\$param contains characters other than space" else echo "\$param consists of spaces only" fi 

「スペースのみで構成される」には、空の(または設定されていない)変数の場合が含まれます。

空白文字をテストすることをお勧めします。 [[ $param = *[^[:space:]]* ]]を使用して、ロケール設定、またはテストする空白文字の明示的なリストを使用します。 [[ $param = *[$" \t\n"]* ]]は、スペース、タブ、または改行をテストします。

iv内の=を使用して文字列をパターンと照合します。 id = “b35cd02f6c”>

はksh拡張機能です(bashとzshにも存在します)。 Bourne / POSIXスタイルでは、case構文を使用して、文字列をパターンと照合できます。標準のシェルパターンでは、ほとんどの正規表現構文のように

^ではなく、!を使用して文字セットを無効にすることに注意してください。

case "$param" in *[!\ ]*) echo "\$param contains characters other than space";; *) echo "\$param consists of spaces only";; esac 

空白文字をテストするために、$"…"構文はksh / bash / zshに固有です。これらの文字をスクリプトに文字通り挿入するか(バックスラッシュ+改行がゼロに展開されるため、改行は引用符で囲む必要があることに注意してください)、または生成することができます(例:

whitespace=$(printf "\n\t ") case "$param" in *[!$whitespace]*) echo "\$param contains non-whitespace characters";; *) echo "\$param consists of whitespace only";; esac 

コメント

  • これはほぼ優れていますが、まだ質問に答えていません。現在、未設定のまたは空のシェル変数とスペースのみを含む変数の違いがわかります。私の提案を受け入れる場合は、シェル変数の設定を明示的にテストする他の回答によってまだ変換されていないparam展開フォームを追加します-つまり、${var?not set}-そのテストに合格して存続しますたとえば、*) caseと一致する変数が最終的な回答に影響することを確認します。
  • 修正-実際、これは最初に尋ねられた質問に答えるが、それ以降、質問の意味を根本的に変えるように編集されているため、答えが無効になっている。
  • mksh[[ $param = *[!\ ]* ]]が必要です。

回答

POSIXly:

case $var in (*[![:blank:]]*) echo "$var contains non blank";; (*) echo "$var contains only blanks or is empty or unset" esac 

空白非空白、未設定

case ${var+x$var} in (x) echo empty;; ("") echo unset;; (x*[![:blank:]]*) echo non-blank;; (*) echo blank esac 

[:blank:]は、水平方向の間隔の文字(Aのスペースとタブ)用です。 SCIIですが、ロケールにはおそらく他にもいくつかあります。一部のシステムには、改行なしスペース(使用可能な場合)が含まれますが、含まれないものもあります。垂直方向のスペース文字(改行やフォームフィードなど)も必要な場合は、[:blank:]を置き換えます。 with [:space:]

コメント

  • POSIXlyは、(おそらくより良い)で動作するため理想的です。ダッシュ。
  • zsh[![:blank:]]に問題があるようで、:bは無効な修飾子です。shおよびkshエミュレートでは、[
  • @cuonglm、何を試しましたか?var=foo zsh -c 'case ${var+x$var} in (x*[![:blank:]]*) echo x; esac'は私にとっては問題ありません。見つからないイベントはインタラクティブシェルのみです。
  • @St é faneChazelas:ああ、そうです、インタラクティブシェルで試しました。:b無効な修飾子は少し奇妙です。
  • @ FranklinYu、OS / Xの場合sh--enable-xpg-echo-default--enable-strict-posix-defaultを使用して構築され、Unixに準拠しています(タブを出力します。

回答

残りの唯一の理由 good スクリプト言語のスクリプトではなく、シェルスクリプトが、極端な移植性が最優先の懸念事項である場合です。従来の/bin/shだけが確実に使用できますが、たとえばPerlはBashよりもクロスプラットフォームで利用できる可能性が あります。したがって、真に普遍的ではない機能を使用するシェルスクリプトを記述しないでください。また、いくつかのプロプライエタリUnixベンダーがPOSIX.1-2001より前にシェル環境を凍結したことを覚えておいてください。

このテストを行うための移植可能な方法がありますが、trを使用する必要があります:

[ "x`printf "%s" "$var" | tr -d "$IFS"`" = x ] 

$IFSのデフォルト値は、便利なことに、スペース、タブ、および改行です。)

printf組み込みはそれ自体が非常に移植性がありますが、echoのどのバリアントを使用しているかを把握するよりも、組み込みに依存する方がはるかに簡単です。)

コメント

  • その’少し複雑です。文字列に特定の文字が含まれているかどうかをテストする通常の移植可能な方法は、case です。
  • @Gilles ‘にcaseグロブを書き込むことは’可能だとは思わない空の文字列、またはのみの空白文字を含む文字列を検出します。 (正規表現を使用すると簡単ですが、caseは正規表現を実行しません’。回答の構成は’改行が気になる場合は機能しません。)
  • ‘が質問であるため、回答の例としてスペースを示しました。を求めました。 ‘空白文字のテストも同様に簡単です:case $param in *[![:space:]]*) …IFS文字をテストする場合は、パターン*[$IFS]*を使用できます。
  • @mikeserv実際には真剣に防御的なスクリプトでは、最初にIFSを明示的に<space><tab><newline>に設定し、その後は二度と触れないようにします。 ‘は気を散らすものだと思いました。
  • パターンの変数に関しては、すべてのBourneバージョンとすべてのPOSIXシェルで機能すると思います。ケースパターンを検出して変数展開をオフにするために追加のコードが必要になり、’それを行う理由を考えることができません。 .profileには、多くのBourneシェルによって実行されたインスタンスがいくつかあります。もちろん、[$IFS]IFSにデフォルト以外の特定の機能がある場合、意図したとおりに実行されません’値(空(または未設定)、]を含み、!または^で始まる) 。

回答

if [[ -n "${variable_name/[ ]*\n/}" ]] then #execute if the the variable is not empty and contains non space characters else #execute if the variable is empty or contains only spaces fi 

コメント

  • これにより、単一のスペースだけでなく、空白文字も削除されます。ありがとう

回答

変数が空であるかスペースが含まれているかどうかをテストするには、次のコードを使用することもできます。

${name:?variable is empty} 

コメント

  • “またはスペースを含む”は正しくありません。
  • 注意してください-現在のシェルを強制終了します。 (:$ {subshell?})に入れる方が良いです。また、-それはstderrに書き込みます-おそらくリダイレクトが必要です。そして、変数が未設定またはnullでない場合、変数’の実際の値に評価される最も重要な。そこに’コマンドがある場合は、それを実行しただけです。 ‘そのテストを:で実行するのが最善です。
  • シェルを強制終了する方法。また、これをテストすることもできます。最初にname=aaaaを定義してから、このコマンドecho ${name:?variable is empty}を実行すると、変数名の値が出力され、このコマンドが実行されますecho ${name1:?variable is empty}出力されます -sh:name1:変数は空です
  • はい-echo ${name:?variable is empty} $name ‘のnull以外の値に評価されるか、シェルを強制終了します。したがって、同じ理由で、’はprompt > $randomvarを実行しないでください。${var?}も実行しないでください。そこに’コマンドがあり、’が実行される可能性があります。’それが何であるかわからない。インタラクティブシェルは’終了する必要はありません。そのため、’終了しません。それでも、いくつかのテストを見たい場合は、ここにたくさんあります。これは’それほど長くはありません…

回答

投稿したコード[[ ! -z $param ]] && echo "I am not zero"は、次の場合にI am not zeroを出力します。 paramは未設定/未定義または空(bash、ksh、zsh)です。

にも paramにスペースのみが含まれている場合(スペースを削除)、POSIXly(シェルの範囲が広い場合):

 [ -z "${param#"${param%%[! ]*}"}" ] && echo "empty" 

説明:

  • ${param# … }は、先頭のテキストを削除します。
  • その先頭のテキストは次のように指定されます:${param%%[! ]*}
  • これはの前のすべてのスペースに展開されます任意の非スペース文字、つまりすべての先頭のスペース。

拡張全体の最終結果は、すべての先頭のスペースが削除されることです。

この展開された結果は、長さが0の場合にテストされます。

  • 結果が空の場合、変数が空であるか、
  • 先頭のスペースを削除します。空にしました。

したがって、テストがtrueの場合、変数はすでに空であるか、内部にスペースしかないかのいずれかです。


概念はさらに簡単に拡張できます。 文字タイプ。 タブも含めるには、ブラケット式内に明示的なタブを配置します:

 [ -z "${param#"${param%%[! ]*}"}" ] && echo "empty" 

または、削除する必要のある文字を含む変数を使用します:

 var=$" \t" # in ksh, bash, zsh [ -z "${param#"${param%%[!$var]*}"}" ] && echo "empty" 

または、POSIXの「文字クラス式」(空白はスペースとタブを意味します)を使用できます:

 [ -z "${param#"${param%%[![:blank:]]*}"}" ] && echo "empty" 

回答

複数行変数を含め、変数にスペースしかないかどうかを確認するには、これを試してください:

[[ $var = *[$" \t\n"]* ]] 

またはxargsを使用:

[[ -z $(echo $var | xargs) ]] 

またはsedを使用:

[[ -z $(sed "/^$/d" <<< $var) ]] 

回答

これを試してください:

$ [[ -z \`echo $n\` ]] && echo zero zero 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です