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

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

新規登録して質問してみよう
ただいま回答率
85.48%
bash

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

ファイル

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

Q&A

解決済

1回答

5496閲覧

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

tktk123

総合スコア11

bash

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

ファイル

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

0グッド

0クリップ

投稿2017/11/15 10:31

###前提・実現したいこと

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文字ずつの処理でも行いたいと思っております

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

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

bash

1$ printf '\n' 2 3 4$ printf '%s' '\n' 5\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/11/15 12:05

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tktk123

2017/12/06 02:01

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問