質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.53%

  • MySQL

    6828questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • bash

    784questions

    bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

  • sh

    337questions

    shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

  • シェル

    279questions

    シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

ヒアドキュメントで実行したSQL結果のエスケープ置換

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,330

moonphase

AWS(Amazon Web Services)総合1位

 やりたいこと

シェルのヒアドキュメントでSQLを実行し、replace関数を使って空白に \ (バックスラッシュ)を付けたい。

 発生している問題

以下に示す通りうまく実行できない。

データ

create table test (
  name varchar(10)
);
insert into test values ('A A'), ('B B B');

 コードと結果(期待通り)

mysql> select replace(name, ' ', '\\ ') from test;
+---------------------------+
| replace(name, ' ', '\\ ') |
+---------------------------+
| A\ A                      |
| B\ B\ B                   |
+---------------------------+
2 rows in set (0.00 sec)

 コードと結果(期待はずれ)

$ cat test1.sh
#!/bin/sh

mysql -N -uroot -ptest testdb<<__EOF__
select replace(name, ' ', '\\ ') from test
__EOF__

$ sh test1.sh
A A
B B B

 コードと結果(期待はずれ)

$ cat test2.sh
#!/bin/sh

mysql -N -uroot -ptest testdb<<__EOF__
select replace(name, ' ', '\\\ ') from test
__EOF__

$ sh test2.sh
A\\ A
B\\ B\\ B

 コードと結果(期待はずれ)

$ cat test3.sh
#!/bin/sh

mysql -N -uroot -ptest testdb<<__EOF__
select replace(name, ' ', '\\\\ ') from test
__EOF__

$ sh test3.sh
A\\ A
B\\ B\\ B

 期待する結果

$ test.sh
A\ A
B\ B\ B
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+2

外れたのでちょっと調べてみました。
--raw (-r) オプションを付けるといいようです。
https://dev.mysql.com/doc/refman/5.6/ja/mysql-command-options.html#option_mysql_raw

$ mysql -N <<EOF
> SELECT replace(CONCAT('abc',CHAR(92),'def'),'\\\\', '\\\\ ') result;
> EOF
abc\\ def
$ mysql -N --raw <<EOF
> SELECT replace(CONCAT('abc',CHAR(92),'def'),'\\\\', '\\\\ ') result;
> EOF
abc\ def

`


以下は回答として間違い。

<<__EOF__ではなく<<'__EOF__'としてください。 ヒアドキュメント内でのbashによるエスケープ処理が回避されます。

#!/bin/sh
mysql -N -uroot -ptest testdb<<'__EOF__'
select replace(name, ' ', '\\ ') from test
__EOF__

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/03 16:02

    こちらも既に試しましたが結果は次の通りです。
    こうなる原因も不明です。

    A\\ A
    B\\ B\\ B

    また、実際のコードではヒアドキュメント内でシェル変数も使いたいので'__EOF__'は使えないんです。

    キャンセル

  • 2017/03/03 16:53

    Y.H.さんの方法で問題が解決しました。

    otnさん、yambejpさんもありがとうございます。
    mysqlコマンドの仕様ということで、理解しました。

    キャンセル

+1

シェル側の問題じゃなくて、標準入力からコマンドを与えた場合には、出力の\\\になるようです(要確認)。

mysql -v -N -uroot -ptest testdb<<__EOF__
select replace(name, ' ', '\\\\ ') from test
__EOF__

mysql -v -N -uroot -ptest testdb \
-e "select replace(name, ' ', '\\\\ ') from test"


それが仕様と確認できれば、出力をsed 's/\\\\/\\/gすればいいかと。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ためしにtestテーブルに「\c」というデータを登録して見るとわかります。
シェルから実行すると「\\c」として返ってきます、なので

select replace(name, ' ', '\\\\ ') from test


で正解です

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • MySQL

    6828questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • bash

    784questions

    bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

  • sh

    337questions

    shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

  • シェル

    279questions

    シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。