問題のスクリプト
こんにちは、なたでです!
前回の「shで文字列の判定がうまくいかない part1」に続いて
引き続き、問題のスクリプトを展開します。(早い)
#!/bin/sh # 2つの文字列を記載 str1="A B" str2="A B" # それぞれ別のファイル名 file1="file1.txt" file2="file2.txt" # 一度保存する echo ${str1} > ${file1} echo ${str2} > ${file2} # 読み込む str1=`cat ${file1}` str2=`cat ${file2}` # 文字列の比較 if [ "${str1}" = "${str2}" ]; then echo "一致してるよ!" else echo "一致してないよ!" fi
さあ、みなさん!
上記のスクリプトを実行するとどうなるでしょう!
ふっふっふ。
さて、先ほどのスクリプトを実行しましょう。
結果は、
一致してるよ!
どうでしたか、
予想はあっていましたでしょうか。
スクリプトのどこに問題があるのか
一見スクリプトは、問題なく見えます。
そして、”A B”と”A B”を比較したので、
「一致してないよ!」と表示されるような感じもします。
では、なぜ「一致してるよ!」とでたのでしょうか。
勿体ぶってもしょうがないので種明かしします。
保存したはずの「file1.txt」と「file2.txt」のテキストの内容を見てみてください。
◆ file1.txt の内容
A B
◆ file2.txt の内容
A B
そうです、file1もfile2も両方とも同じ”A B”になっているのです。
2つのスペースはどこいったのでしょうか……
実は以下のコード
#!/bin/sh # 2つの文字列を記載 str1="A B" str2="A B" # それぞれ別のファイル名 file1="file1.txt" file2="file2.txt" # 一度保存する echo ${str1} > ${file1} echo ${str2} > ${file2}
このコードは実行時は次のようになります。
#!/bin/sh # 一度保存する echo A B > file1.txt echo A B > file2.txt
ここでポイントとなっているのが、
echo A B echo A B
という echo
です。
実際に実行してみると、この時点で2つのスペースは消えます。
> echo A B A B > echo A B A B
なぜ消えてしまうのかいうと、
echo A B
は、echo
プロセスに対して、
引数1にA、引数2にBを渡すという意味になり、
echo
は渡された引数(引数1と引数2)を、
半角スペースで結合した文字を表示ということになります。
つまり、半角スペースは引数を分けるための
デリミタ(区切り文字)として利用されたということなのです。
解決策と結論
解決策として半角スペースをデリミタ(区切り文字)として認識させないように
ダブルクォーテーションでくくる方法があります。
> echo "A B" A B > echo "A B" A B
最初のスクリプトを直してみましょう。
#!/bin/sh # 2つの文字列を記載 str1="A B" str2="A B" # それぞれ別のファイル名 file1="file1.txt" file2="file2.txt" # 一度保存する echo "${str1}" > "${file1}" echo "${str2}" > "${file2}" # 読み込む str1=`cat "${file1}"` str2=`cat "${file2}"` # 文字列の比較 if [ "${str1}" = "${str2}" ]; then echo "一致してるよ!" else echo "一致してないよ!" fi
文字列には半角スペースが含まれる可能性を加味し、
ダブルクォーテーションでくくることが大事なのです!
ちなみにこれを解決する策としてはダブルクォーテーションで囲う以外に、
IFS(Internal Field Separator)という環境変数を変更してしまうという手もあります。
#!/bin/sh # IFS を:に変更する oldifs=${IFS} IFS=: # 2つの文字列を記載 str1="A B" str2="A B" # それぞれ別のファイル名 file1="file1.txt" file2="file2.txt" # 一度保存する echo ${str1} > ${file1} echo ${str2} > ${file2} # 読み込む str1=`cat ${file1}` str2=`cat ${file2}` # 文字列の比較 if [ "${str1}" = "${str2}" ]; then echo "一致してるよ!" else echo "一致してないよ!" fi # IFS を元に戻す IFS=${oldifs}
以上。
本当は怖いshでの文字列操作でした。
最後まで読んでいただき、ありがとうございます!
コメント