- ベストアンサー
DOSコマンドのダブルクォーテーションの扱い
DOSコマンドでダブルクォーテーションを検索し、 リダイレクションをすることが出来なくて困っています。 例えば findstr "\"!" a.txt は出来ますが findstr "\"!" a.txt >b.txt とするとリダイレクションが出来ません。 grepも同じようです。 またunixコマンドではシングルクオートは、「囲まれた中身をそのままの文字として利用」し、ダブルクオートは、「囲まれた中身に$HOME など $ で始まる文字列があれば、 それを環境変数、シェル変数といった、値に置き換えてから、利用する」という明確な違いがありますが、DOSコマンドでは明確な違いはあるのでしょうか? unixのshellをDOSコマンドに移植しています。 DOSコマンドの参考Webもあまり見つからなくて困っています。 もし参考になりそうなWeb等ありましたら教えてください。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
"と'の違いですが、cmd.exe では ' 特殊文字ではありません。for /f 文のある形式で意味を持つだけでそれ以外の場所では#+-/などと同じ普通の文字です。unixのシェルとは全然違います。 まず質問文の >findstr "\"!" a.txt >b.txt ですが、\ はfindstrが正規表現の特殊文字として扱うだけでCMDの構文解析では普通文字なので、"\"が引用符に囲まれた文字列として扱われます。次の!は引用符の外の文字。次の " a.txt >b.txtが、(終りの引用符の欠けた)引用符に囲まれた文字列とみなされますので、リダイレクト記号は引用符の中となり効きません。 >OKだったもの >findstr ^"\^"!^" a.txt >findstr \^"! a.txt ^を前置した"は引用符としての意味を失い、そのまま"がfindstrにわたされます。リダイレクト記号をつけても引用符の中で無いので効きます。findstrは検索文字列が"で囲まれていればそれを外して、囲まれていなければそのままが使われますので、どちらでも同じ結果になります。 >以下待ちになるもの >findstr ^"! a.txt findstrに "! a.txt が渡るのでa.txtも検索文字列の一部とみなされます(閉じる"がfindstrによって補われる)。従って、標準入力から、! または a.txt という文字列を含む行を探していることになります。 リダイレクトをつけると引用符の外なので効きます。 >findstr "^"!" a.txt 引用符の中で^は"をエスケープしないので1個目と2個目の"がペアになり^を囲み、3個目はペアの欠けた引用符となり a.txtを囲みます。リダイレクトをつけても引用符の中なので効かないはず。 その後、findstrが文字列を囲む""を外すので、^!つまり行頭の!または a.txtを含む文字を標準入力から探すことになります。 >findstr ^"!^"^" a.txt ^が前置されているので"はCMD的には引用符でなくなりますのでリダイレクトは効きます。 findstr には "!"" a.txt が渡り、文字列を囲む""が外されて、!またはa.txtを含む文字列を標準入力から探す。 >findstr ^" a.txt 同様。 >コンソールには表示できるがリダイレクションでエラーになるもの >findstr \"! a.txt >b.txt cmd的には"は引用符なので>b.txtも(終りの欠けた)引用符の中なのでリダイレクトは効きません。 findstr にわたるのは \"! a.txt >b.txtで、検索文字列が "! で残りがファイル名とみなされますが、「a.txt >b.txt」という名前のファイルが無いのでエラー リダイレクトをつけないで >findstr \"! a.txt だと、findstr には \"! a.txt が渡り、検索文字列が "! で、ファイル名がa.txtとなり目的通りになります。 >「"」を検索するには「\^」をつけるということでしょうか。 CMDに引用符とみなされないように^をつけて(この^はCMDが外してからfindstrに渡す)、findstrが"を外さないようにさらに\を前置する必要があるということです。 CMDがまず最初に^や"や>をどのように処理して、次にfindstrが渡された文字列をどう解釈するか段階を分けて考えればわかると思います。これはunixのシェルでも同じですが。 unixのシェルと比べるとCMDの"は変態的です。
その他の回答 (2)
- utakataXEX
- ベストアンサー率69% (711/1018)
Unix系(と言うかC/C++やJavaも)でエスケープと言えばバックスラッシュですが、DOSのエスケープはキャレット(^)です。 どんな検索を使用としているかわからないので適当ですが、あれこれ試してみてください。 findstr ^"\^"!^" a.txt > b.txt
お礼
ありがとうございました。 あれこれ試すというのはとても重要ですね。数個しか試さないで質問を投げてしまいました。反省してます。
- kmb01
- ベストアンサー率45% (63/138)
エスケープは^です。 findstr ^"! a.txt >b.txt でどうでしょう
お礼
ありがとうございます。 ご回答を参考にいろいろやってみたら出来ました。 検索したい文字は「"!」の2文字でした。 結果をご報告したいと思います。 OKだったもの findstr ^"\^"!^" a.txt findstr \^"! a.txt 以下待ちになるもの findstr ^"! a.txt findstr "^"!" a.txt findstr ^"!^"^" a.txt findstr ^" a.txt コンソールには表示できるがリダイレクションでエラーになるもの findstr \"! a.txt >b.txt 「"」を検索するには「\^」をつけるということでしょうか。 「windowsヘルプ」の「文字列リテラル」のページでは 「\"」が二重引用符「\^」がカレットと別れています。 なぜ両方が必要なのか解説して下さる方いらっしゃいませんでしょうか。修正本数が莫大なので、理解しないで手をつける事が出来ない状態なので。 ”と’の違いもお解りになりましたらお願いしたいです。
お礼
詳細なご説明どうもありがとうございました。とても良くわかりました。 他のコマンドにも応用しながら移植がんばりたいと思います。 まだまだ難関が待ち受けていそうなのでその時はまたよろしくお願い致します。