はじめに
xml データを以下コマンドによりファイルに出力した際、データ中のダブルクォートが削除されていたという意図せぬ挙動になったので、その原因と対応策についてメモしたいと思う。
コマンドは以下:
echo "ダブルクォートを含む xml データ" > file.xml
TL;DR
- 内容にダブルクォートが含まれる場合は、シングルクォートで囲む
- 内容にシングルクォートが含まれる場合は、ダブルクォートで囲む
- 内容にシングルクォートとダブルクォート両方が含まれる場合は、ヒアドキュメントを利用する
ダブルクォートが含まれる場合
ダブルクォートのみが含まれる内容の時は、シングルクォートで囲むことで、正常に出力される。
echo 'this is a "pen"' > file
cat file
# this is a "pen"
ダブルクォートをダブルクォートで囲むと、"
がなくなってしまう。
echo "this is a "pen"" > file
cat file
# this is a pen
シングルクォートが含まれる場合
シングルクォートのみが含まれる内容の時は、ダブルクォートで囲むことで、正常に出力される。
echo "this is a 'pen'" > file
cat file
# this is a 'pen'
シングルクォートをシングルクォートで囲むと、'
がなくなってしまう。
echo 'this is a 'pen'' > file
cat file
# this is a pen
シングル/ダブルクォーテーションが両方含まれる場合
そのまま出力
この場合は少し特殊で、単純な echo や cat コマンドでは対応できなかったため、ヒアドキュメントを利用する。1
cat <<EOF > file
this is a "pen" and that is an 'eraser'
EOF
cat file
# this is a "pen" and that is an 'eraser'
ダブルクォートに寄せる
cat file
# this is a "pen" and that is an 'eraser'
cat file | sed "s/'/\"/g" > file
cat file
# this is a "pen" and that is an "eraser"
シングルクォートに寄せる
cat file
# this is a "pen" and that is an 'eraser'
cat file | sed "s/\"/'/g" > file
cat file
# this is a 'pen' and that is an 'eraser'
おまけ
エイリアスにしてみた
~/.zshrc
alias tosq='sed "s/\"/'\''/g"' # to single quote
alias todq='sed "s/'\''/\"/g"' # to double quote
使用例:
# cat 経由
cat file | todq
# this is a "pen" and that is an "eraser"
# 文字列を直接渡しても良いが、その場合はダブルクォートを `\` でエスケープする
echo "this is a \"pen\" and that is an 'eraser'" | tosq
# this is a 'pen' and that is an 'eraser'
関数にしてみた
~/.zshrc
ftosq() {
echo $1 | sed "s/\"/'/g"
}
ftodq() {
echo $1 | sed "s/'/\"/g"
}
使用例:
# 文字列直接渡す
ftodq "$(echo this is a \"pen\" and that is an \'eraser\')"
# this is a "pen" and that is an "eraser"
# cat 経由
ftosq "$(cat file)"
# this is a 'pen' and that is an 'eraser'
今回は関数にしてもあまりメリットがないかもしれない。
-
中身のダブルクォートをエスケープすることで、このようなやり方をせずとも目的を達成できるのだが、ここでは元のデータをいじらないことに重きを置くことにする。 ↩