Bashの文字列で特殊文字を使う方法
2020/02/20更新
目次
概要
Bashで、タブをgrepしようとしてgrep -e "\t" file.txt
としてもうまくいかない。また、シングルクォートの中でシングルクォートを記述しようとして、echo 'I don\'t know.'
などとしてもやはりうまくいかない。このように、Bashにおける文字列のクォートでは、他のプログラミング言語でよく使われている\
によるエスケープ記法が使えず、特殊文字を記述したくなったとき初めは戸惑ってしまう。そこで、Bashにおいて特殊文字を記述したい場合の方法をここにまとめておく。
Bashにおける文字列のクォート
Bashで、ダブルクォートとシングルクォートの主な使い分けは、変数展開をするかどうかである。シングルクォートは\
によるエスケープは一切使えないため、'
を記述することは不可能となる。また、特殊文字もそのものを直接入力するしかない。ダブルクォートの中では、"
など一部の文字は\
によるエスケープが使えるものの、特殊文字などはやはり直接入力するしかない。
一方で、クォートの外では、$'~'
という記法によって、よくあるC言語スタイルの\
によるエスケープを記述できる。実はこれは「クォートの外」ではなく、$'~'
という別の種類のクォート(ANSI-C Quoting)である。
Bashでは文字列を連結する演算子は特に無く、ただ並べて書けば自動的に文字列が連結される。そのため、必要に応じてこれらのクォートを文字列の途中で使い分ければよい。
ダブルクォートの中 | シングルクォートの中 | クォートの外 | |
---|---|---|---|
改行 | 直接入力 | 直接入力 |
|
タブ | 直接入力(※1) | 直接入力(※1) |
|
その他の制御文字 | 直接入力(※2) | 直接入力(※2) |
|
ダブルクォート |
|
|
|
シングルクォート |
| (不可) |
|
バッククォート |
|
|
|
バックスラッシュ |
|
|
|
ドル |
|
|
|
※1:ターミナルでタブ文字を直接入力するには、Ctrl+
v
を押した後にタブキーを押すと入力できる。シェルスクリプトとして作成する場合は、単にエディタ上でタブを入力すればよい。※2:その他の制御文字は、Ctrl+
v
を押した後に、キャレット記法で使う文字をCtrlと同時に押すことで入力できる。例えば、「Ctrl+v
Ctrl+[
」と続けて押すとエスケープ文字\e
が直接入力できる。このとき、画面上はキャレット記法で^[
と表示される。
なお、コマンド置換で使われるバッククォート`~`
は、文字列のためのクォートではないため、その中は基本的にクォートの外と同じであるが、`
や\
はエスケープする必要があるため、バッククォートの中でバッククォートを使う場合は注意が必要である。
例
タブ文字をgrepしたい
ANSI-C Quotingで\t
を使うか、または直接入力すればよい。以下の例で、空白のように見える部分は、実際にはタブ文字を直接入力する。
# タブを検索 grep -e $'\t' file.txt grep -e " " file.txt # タブを含む文字列を検索 grep -e hoge$'\t'fuga file.txt grep -e "hoge fuga" file.txt # タブから始まる行を検索 grep -e ^$'\t' file.txt grep -e "^ " file.txt
シングルクォートの中でシングルクォートを使いたい
シングルクォートの中でシングルクォートは使えない。シングルクォートの部分だけ別のクォートを使うか、クォートを閉じて裸で\'
と記述すればよい。
# クォートを一度閉じて裸で\'と書く。 echo 'I don'\''t know.' # シングルクォートの部分だけダブルクォートにする。 echo 'I don'"'"'t know.'
改行を含む文字列を変数に代入したい
ANSI-C Quotingで\n
を使うか、または可読性は落ちるが直接記述することもできる。
# $'~'を使う。 str=hoge$'\n'fuga str=$'hoge\nfuga' # クォートの中で直接改行する。 str="hoge fuga"
改行を含む文字列をechoしたい
前述のようにして改行を含む文字列を代入した変数をechoする場合は、ダブルクォートで囲む必要がある。あるいは、echoコマンドの場合は、-e
オプションを使うことで、見慣れた\
によるエスケープを直接使用することもできる。
str1=hoge$'\n'fuga str2='hoge\nfuga' echo "$str1" # hoge # fuga echo "$str2" # hoge\nfuga echo -e $str2 # hoge # fuga
制御文字をechoしたい
エスケープシーケンスによって文字色をつけるなどの目的で制御文字を出力したい場合は、ANSI-C Quotingを使えばよい。
echo $'\e[31mhoge\e[0m' # 赤い文字の「hoge」が出力される
バッククォートを使いたい
バッククォート`
はシングルクォートの中以外ではコマンド置換になってしまうため、\`
とエスケープする必要がある。バッククォートの中でバッククォートを文字列として使う場合は、二重にエスケープが必要となるので注意が必要である。ちなみに、バッククォートによるコマンド置換はネスト(入れ子)ができないと思われがちだが、実はこのように適切にエスケープをすれば(大変な労力が伴うので通常は推奨されないが)ネストをすることは可能である。
# 以下はいずれも「`」を出力する echo \` echo '`' echo "\`" echo `echo \\\`` echo `echo '\`'` echo `echo \`echo \\\\\\\`\`` # 以下はエスケープが不適切なため、いずれもエラーとなる echo ` echo "`" echo `echo \`` echo `echo '`'`