Ansatzの備忘録

勉強したことあるいはふと思い立ったこと

シェルワンライナー160本ノック問題15

問題15 文字種の変換

echo 英文字列 に適当なワンライナーをつなげて大文字へ変換せよという問題だった。いろいろとわからないことが出てきた。

まず自分は

echo I am a perfect human | echo ${1^^}

でいいんじゃないかと思ってやってみたがうまくいかなかった。$1 というものがなんなのか結局まだよくわかってないのだと思う。これは引数を受け取るための変数だが、パイプから流れてきた出力を受け取ることはできないのだろうか。そこがよくわからない、bash のマニュアルのどこかにかいてあるのだろうか。

${1^^} の^^という処理についても考えてみるとよくわからない。マニュアルには^^の後ろを省略すると正規表現の ? として処理され、すべての文字に一致すると書いてあった。だが ? は直前の文字が0個または1個のとき一致するという記号であり、いまみたいに直前の文字が何もない状況だと無が指定されるような気がする。どういう処理がされているのかなんだかよくわからない。と思っていたがマニュアルをよく検索してみると

?      任意の 1 文字にマッチします。

と書いてあった。ググって出てくる話と違うではないか。どういうことなんだろうか。bash での正規表現は普通とは違うものになっているのだろうか。

 

追記

これはワイルドカードと呼ばれる記号で、正規表現とはまた別物らしい。詳細はのちに投稿する練習2.3.bに書いておく。

 

最初の小問の正解は

echo I am a perfect human | (read a; echo ${a^^})

である。なぜかっこが必要なのかは今後の問題で扱うそうなので今は触れないでおく。

 

次の小問の正解は

echo pen-pinapple-apple-pen | (IFS='-'; read -a w; echo "${w[*]^}")

である。今度は区切り文字を変更して配列を用いている。クォートしていることで出力にハイフンが出る。ハイフンで区切られた単語はそれぞれが配列の要素に個別に入る。そして配列の変数展開をして各要素の先頭の文字を変換している。