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

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

ただいまの
回答率

90.51%

  • bash

    648questions

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

  • ファイル

    170questions

    ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

bashでのファイル読み書き時のバックスラッシュのあつかい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 409

tktk123

score 3

前提・実現したいこと

bashによるエスケープ文字?の入ったテキストファイルの読み書き時にて
そのままの内容を抜き出したい

バックスラッシュをそのまま読み出し書き込み行いたい

発生している問題・エラーメッセージ

テキストファイル内の[ \026 ]というようなバックスラッシュ入りの文字列を
読み込み,書き込みした際に書き込み先のテキストファイルでは[ ^V ]という文字列になってしまう

該当のソースコード

#!/bin/bash

count=1
while read -r  LINE ;do

        printf  "${LINE}" >> text${count}.txt

        count=$((count+1))

done< grp.txt

試したこと

上記のコードのようにバックスラッシュをエスケープ文字として扱わないオプションの [ -r ]を
readに入れた

補足事項

今回は1行に対する処理なのですが,理想としてはこのバックスラッシュをそのまま読み書きするのを1文字ずつの処理でも行いたいと思っております

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

うまくいってない原因は「せっかく-rをつけてエスケープシーケンスを解釈しないようにした」のに、printfがエスケープシーケンスとして解釈したためと思います。

$ printf '\n'


$ printf '%s' '\n'
\n

おわかりでしょうか?printfコマンドは第一引数があたかもC言語の文字列リテラルの内側に書かれた文字列であるかのように解釈するんですね。echoがあるのになぜprintfコマンドが必要かよく考えてみると「あ!そうか」と気づけると思います。お気づきと思いますが、それは書式付きの出力をしたいからです。

ということで

 printf  '%s' "${LINE}" >> text${count}.txt

とすればよいと思います。また行ごとに改行文字を付加したいなら以下のように。

 printf  '%s\n' "${LINE}" >> text${count}.txt


すでにお気づきと思いますが、printfの第一引数は%sやエスケープシーケンスを特別な意味に解釈しますので、本来はシェル変数(の展開結果)を用いるべきではないと思います(特別なトリックを意図するのでない限りは)。特に本件では利用者からの入力をそのままprintfの第一引数に指定しようとしています。エスケープシーケンスの話がなかったとしてもそれは不適切な用法と言えるでしょう。

printfコマンドではprintf '%d %d' 1などのように書式文字列と引数に不整合があっても特に何も問題は起きませんが、これがC言語で書いたsprintfだったら大変なことになります。下手をするとSQLインジェクションの原因に・・・

シングルクォート、ダブルクォート、バッククォート等々の使い方や、各コマンドに指定した引数に含まれた特殊なシーケンスがどう解釈されるかはわりとややこしいので、混乱を招きがちです。曖昧にせずに必要に応じて調べたり実際にやってみて確認し覚えてゆくと良いと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/06 11:01

    各コマンドについての理解が浅くprintfがエスケープしていないのは盲点でした....
    ですが丁寧な解説も頂けたおかげで理解でき無事うまく回るようになりました本当にありがとうございました

    キャンセル

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

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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

  • bash

    648questions

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

  • ファイル

    170questions

    ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。