次のbash構文は、param
が空でないかどうかを確認します。
[[ ! -z $param ]]
例:
param="" [[ ! -z $param ]] && echo "I am not zero"
出力なしで問題ありません。
ただし、param
は、1つ(または複数)のスペース文字を除いて空です。大文字と小文字は異なります:
param=" " # one space [[ ! -z $param ]] && echo "I am not zero"
「私は違いますゼロ」が出力されます。
空白文字のみを含む変数を空と見なすようにテストを変更するにはどうすればよいですか?
コメント
回答
まず、 -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
man test
から:-z STRING - the length of STRING is zero
。$param
のすべてのスペースを削除する場合は、${param// /}
trim()
関数が組み込まれていません* nixはありますか?非常に単純なことを実現するためのさまざまなハックがあります…[[ ! -z $param ]]
はtest ! -z $param
。