改行はどこへ消えた?(bashの変数)


(TVアニメ『小林さんちのメイドラゴン』OP主題歌「青空のラプソディ」 fhána)
fhánaいいですねえ。
この歌の伴奏で何と言ってるのでしょうか。ちゅちゅゆ? without you? この聞き取れない感じがまたいいです。
アニメの方ですが、小林さんちで住み込みメイドするドラゴンとそれに愛される小林さんのコメディです。ドラゴンネタ楽しいです。特に洗濯と料理。便利な口と尻尾ですねえ。
ドラゴンの姿のままだと巨大すぎて、小林さんちに入らないので、人間の女性に変身できるのですが、しっぽは生えたままです。ドラゴンって何でもできるんですね。私も通勤に使いたいです。

ドラゴンは小さくならないと部屋に入りませんが、変数には大きな文字列も入ります。今回はbashの変数について考えてみましょう。
変数aを用意して適当に数字を入れてみます。

takk@deb83:~$ a="1 2 3 4 5 6 7 8 9 10"
takk@deb83:~$ echo $a
1 2 3 4 5 6 7 8 9 10

echoコマンドを実行すると、変数に格納されたままの文字列が表示されました。

変数の内容を置換して表示してみます。

takk@deb83:~$ echo $a | tr ' ' .
1.2.3.4.5.6.7.8.9.10
takk@deb83:~$ echo ${a// /.}
1.2.3.4.5.6.7.8.9.10
takk@deb83:~$ 

次は改行付きの文字列を格納してみましょう。
seqコマンドは以下のように、数列を生成するコマンドです。

takk@deb83:~$ seq 10
1
2
3
4
5
6
7
8
9
10
takk@deb83:~$ 

seq 10の結果を変数bに格納し、その後変数bをechoすると、

takk@deb83:~$ b=`seq 10`
takk@deb83:~$ echo $b
1 2 3 4 5 6 7 8 9 10
takk@deb83:~$ 

あら不思議。改行が消えました。代わりに空白になっています。

では、変数aと同じように空白を.(ドット)に置換してみましょう。

takk@deb83:~$ echo $b | tr ' ' .
1.2.3.4.5.6.7.8.9.10
takk@deb83:~$ 

trコマンドでは問題なく置換できました。次はbashのブレース展開で置換してみます。

takk@deb83:~$ echo ${b// /.}
1 2 3 4 5 6 7 8 9 10
takk@deb83:~$ 

あれ、空白のままです。何故なんでしょう。

実はbash変数に格納された改行は、消えたのではなく表示時のみ空白にされているのです。
改行を含んだ形で変数の文字列を取り出すには、””で変数名を囲みます。

takk@deb83:~$ echo "$b"
1
2
3
4
5
6
7
8
9
10
takk@deb83:~$ 

bannerコマンドを使って試してみましょう。

takk@deb83:~$ c=`banner MAID DRAGON`
takk@deb83:~$ echo $c
# # # ### ###### ## ## # # # # # # #(省略)
takk@deb83:~$ 

“”なしの場合は、一行で表示されました。一方””ありはの場合は、下のようにバナーが表示されます。

改行が消えていないことは分かりました。では、ブレース展開で置換するにはどうすれば良いのでしょう。
bashで改行を表す$’\n’を使います。

takk@deb83:~$ echo ${b//$'\n'/.}
1.2.3.4.5.6.7.8.9.10
takk@deb83:~$ 

置換できました。

PATHを複数行に分離する応用もできます。

takk@deb83:~$ grep usr <<< "${PATH//:/$'\n'}"
/usr/local/bin
/usr/bin
/usr/local/games
/usr/games
/usr/local/bin/
takk@deb83:~$ 

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA