問題のスクリプト
こんにちは、なたでです!
前回の「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での文字列操作でした。
最後まで読んでいただき、ありがとうございます!



コメント