web-dev-qa-db-ja.com

Bashで文字列に空白以外の文字が含まれているかどうかをテストします

私のスクリプトはid3タグを読み取って表示しています。フィールドが空白の場合、不明なエコーをエコーさせようとしていますが、試行するすべてのifステートメントが機能しません。 id3タグは固定サイズであるため、nullになることはありませんが、値がない場合は空白で埋められます。つまり、タイトルタグの長さは30文字です。これまで私は試しました

echo :$string: #outputs spaces between the 2 ::

if [ -z "$string" ] #because of white space will always evaluate to true

x=echo $string | tr -d ' '; if [ -z "$string" ];#まだtrueと評価されますが、エコーします:$ x:エコーします::

スクリプト

#!bin/bash
echo "$# files";
while [ "$i" != "" ];
do
   TAG=`tail -c 128 "$i" | head -c 3`;
   if [ $TAG="TAG" ]
   then
      ID3[0]=`tail -c 125 "$1" | head -c 30`;
      ID3[1]=`tail -c 95 "$1" | head -c 30`;
      ID3[2]=`tail -c 65 "$1" | head -c 30`;
      ID3[3]=`tail -c 35 "$1" | head 4`;
      ID3[4]=`tail -c 31 "$i" | head -c 28`;
      for i in "${ID3[@]}"
      do
         if [ "$(echo $i)" ] #the if statement mentioned
         then
            echo "N/A";
         else
            echo ":$i:";
         fi
      done
   else
      echo "$i does not have a proper id3 tag";
   fi
   shift;
done
21
Yamiko

Bashの正規表現構文を使用できます。

二重角かっこを使用する必要があります[[ ... ]]、(一般的に、より用途が広い)。
変数を引用符で囲む必要はありません。正規表現自体してはいけません引用する

for str in "         "  "abc      " "" ;do
    if [[ $str =~ ^\ +$ ]] ;then 
      echo -e "Has length, and contain only whitespace  \"$str\"" 
    else 
      echo -e "Is either null or contain non-whitespace \"$str\" "
    fi
done

出力

Has length, and contain only whitespace  "         "
Is either null or contain non-whitespace "abc      " 
Is either null or contain non-whitespace "" 
7
Peter.O

これらの回答の多くは、本来あるべきよりもはるかに複雑であるか、はるかに読みにくいものです。

[[ $string = *[[:space:]]* ]]  && echo "String contains whitespace"
[[ $string = *[![:space:]]* ]] && echo "String contains non-whitespace"
31
Charles Duffy

非bash固有の、シェルのみのバリアント:

case "$string" in
 *[!\ ]*) echo "known";;
 *) echo "unknown";;
esac
3

拡張グロブが有効になっている場合(shopt -s extglob):

if [ -n "${string##+([[:space:]])}" ]; then
    echo '$string has non-whitespace characters'
fi
1
Eugene Yarmash
[[ -z `echo $string` ]]

バッククォートは、;内でコマンドを実行します。 bash行の解析では、タブと改行が空白に変換され、二重の空白が結合されます。 echoコマンドは、この文字列を再発行します。この文字列は、[[]]による最終テストのために空の文字列に縮小されます。これは、以下を通過する最短のソリューションだと思います。

> VAR="$(echo -e " \n\t")"
> [[ -z  `echo $VAR` ]] ; echo $?
0
> VAR="$(echo -e " \na\t")"
> [[ -z  `echo $VAR` ]] ; echo $?
1
> VAR="$(echo -e "aaa bbb")"
> [[ -z  `echo $VAR` ]] ; echo $?
1
> VAR=
> [[ -z  `echo $VAR` ]] ; echo $?
0
1
Peter Steier
if [ "$(echo "$string" | tr -s ' ')" == " " ]; then
  echo "all white space"
fi

これにより、繰り返されるすべてのスペースが1つのスペースに圧縮され、それが比較されます。

0
ams

可能な限りシンプルに保ちながら、二重括弧[[]]を必要としないよりポータブルな方法を共有します。

空白または= nullのみを含む文字列を検出します。

if [ -z "${string// }" ]; then <do something>; fi

この場合は次のようになります。

${var// }

といった:

if [ -z "${string// }" ]; then echo "It's empty!"; fi

これは、置換によってすべての空白をnullに置き換えるだけです。 $ stringに空白のみが含まれている場合、-zテストはTRUEと評価します。文字列に空白以外の文字がある場合、方程式はFALSEと評価されます。

BASHについてさらに詳しく説明すると(OPがBASHでこれについて質問したため)、上記の例ではタブをキャッチできませんが、タブをキャッチすることは可能です。期待どおりに機能する、または機能しないBASHの例をさらに示します。

検索文字列にタブがあるとしましょう。

これは機能します:

string=$(echo -e "\t"); if [ -z ${string// } ]; then echo "It's empty!"; fi

しかし、これらはしません:

string=$(echo -e "\t"); if [ -z "${string// }" ]; then echo "It's empty!"; fi
string=$(echo -e "\t"); if [ -z '${string// }' ]; then echo "It's empty!"; fi

上記の最後の2つの例は、どちらも文字列が空ではないことを報告しています。タブを空白と見なす場合、それは問題になるため、最初の例を使用する必要があります。

改行はどうですか? \nシナリオを見てみましょう。まず、「正しい」動作はあなたの期待に依存します。

これらは改行(\n)を空白として扱います(方程式はTRUEと評価されます):

string=$(echo -e "\n\n"); if [ -z ${string// } ]; then echo "It's empty!"; fi
string=$(echo -e "\n\n"); if [ -z "${string// }" ]; then echo "It's empty!"; fi

これはそうではありません(方程式はFALSEと評価されます)。つまり、この方程式は改行が空白ではないと見なします。

string=$(echo -e "\n\n"); if [ -z '${string// }' ]; then echo "It's empty!"; fi

改行、タブ、スペースをチェックする必要がある場合は、2つのIF/THENステートメントまたは上記のCASEメソッドを使用する必要がある場合があります。

0
MrPotatoHead

これはゼロの長さまたはスペースまたはタブをチェックします

S="Something"
if [[ "x$S" == "x" || "x$S" == x*\ * || "x$S" == x*\    * ]] ;then
  echo "Is not OK"
else
  echo "Is OK"
fi
0
alian