• ベストアンサー

sedで\を含む文字列へ変換

テキストファイルの中で zeta0 となっている部分を \zeta_0^p へ一括して変換したいのですが、 tex でコンパイルできるソースに変換するために ネット上の情報を参考にして $ sed -e "s/zeta0/\zeta_0^p/" 01.tex > 02.tex $ sed -e "s/zeta0/\\\zeta_0^p/" 01.tex > 02.tex $ sed -e "s/\zeta0\/\\\zeta_0^p\/" 01.tex > 02.tex $ sed -e "s/zeta0/\\\zeta_0^p&/g" 01.tex > 02.tex などとやってみましたが、どれもうまくいきません。 どう書けばうまくいきますか? 教えて下さい。 よろしくお願いします。

noname#197096
noname#197096

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

sed -e "s/zeta0/\\\zeta_0^p/" 01.tex > 02.tex 一応、これでも動くはずですが。 どのように「うまくいきません」なのでしょうか? 引数の作り方ですが まず、sedに送りたい文字列を考えます s/zeta0/\\zeta_0^p/ \は、sedで解釈されて、メタ文字の切り替えや引用等に使われます。 そのため、\という文字を扱うには\\とする必要があります。 次に、シェルで、上記文字列を表現する方法を考えます。 ダブルクオートは、\によるエスケープシーケンスを解釈して置換します。 そのため、\という文字を扱うには\\とする必要があります。 "s/zeta0/\\\\zeta_0^p/" ※ 3つでも動いたのは、 ダブルクオートの場合は\zというシーケンスが無く、変換されずに残ったためです。 ですが、この文字列の中では、変数展開などを使っていません。 ならば、シングルクオートを使えば、特殊文字の展開やエスケープを考えずに済みます 's/zeta0/\\zeta_0^p/' set -x と入力したあと各コマンドを実行すると、上記のシェルによる置き換え後のコマンドラインが表示されるので、自分の期待る文字列になっているか確認できます。 シェルの種類によっては、上記の展開が違う場合もあります。

noname#197096
質問者

お礼

昨日は zeta0 aaazeta0aa aazeta0aa zeta0 という内容の4行のファイルを質問の中で書いたコマンド群で変換すると zeta_0^p aaazeta_0^paa aazeta_0^paa zeta_0^p となっていたのです。 今 sed -e "s/zeta0/\\\zeta_0^p/" 01.tex > 02.tex のコマンドを打つと こちらが期待したように変換してくれました。 昨日はどこかミスをしていたのかもしれません。 上記の内容は完全には理解できませんでしたが、 おかげさまで勉強になりました。 http://okwave.jp/qa/q3340542.html を参照して変数展開もできるようになりました。 どうもありがとうございました。

関連するQ&A

  • sed で \ を含む文字列に置換

    現在、非常に多数のドキュメントの整形を LaTeXを使って自動的に行っています。 問題となっている処理のエッセンスを抜き出すと次のようなもので、テンプレートファイル中の __PATTERN__ という文字列を、その都度指定する文字列($string)に置換した後にplatexでコンパイルする、という流れです。 ---------- #!/bin/bash sed "s/__PATTERN__/$string/" < template.tex > document.tex platex document.tex ---------- 問題は、$string に '_'(アンダーバー)が含まれるケースで、platexのコンパイルでエラーが発生します。 これを回避するには、'_' を '\_' に置換する必要がありますが、上記処理の前に、$string 中の '_' を '\_' に置換する処理を加えても、上記処理の段階で '\' が消えてしまいます。 肝は sed でのエスケープのやり方だと思うのですが、どうにもうまく行きませんので、お知恵を拝借できればと思います。 なお、tex ファイル中、__PATTERN__ は、他のコマンドの引数内で使用されているため、\verb+ + で囲むという手段も使えません。

  • 複数のファイルをsedで処理したいけど・・・

    こんにちは。sedでテキストファイルの文字の変換をしています。でも、 001.txt 002.txt 003.txt のように同じ変換をしたいファイルが延々とあります(涙) sed -e 's/a/b/g' 001.txt > 001convert.txt のように一つずつやっているととても大変です。 なのでワイルドカードが使えるかなと sed -e 's/a/b/g' *.txt > *convert.txt とやったら「*convert.txt」というのが一つだけできてしまいました。 変です・・・。 正しくはどのようにコマンドを書けばいいのですか? 教えてください!!

  • sedコマンドに関して

    サーバーにあるファイルの中身を置換する為 Tera Termのsedコマンドを使おうとしたのですが 文字列の「'」が置換できません。 以下のように入力してみましたがだめでした。 sed -e 's/'/'aa/g' text1.txt > text2.txt sed -e 's/\'/\'aa/g' text1.txt > text2.txt 出来ないんでしょうか!? 宜しくお願いいたします。

  • ターミナルでsedを使って連続する空白をひとつの=に変換したいのですが

    ターミナルでsedを使って連続する空白をひとつの=に変換したいのですが、うまく出来ず困っています。 普通のLinuxでは出来たのですが、MacOSXだと出来ません。 どうしたら変換出来ますでしょうか? df -k / | tail -n 1 | sed -e "s/ \+/=/g"

  • sedやperlでの2バイト文字を含む変換

    こんにちは。 sedコマンドは、texに付属していた日本語対応のものを使用しており、 perlはWindows用のActive Perl v.5.12.2を使用しています。 カレントディレクトリにあるファイルやフォルダにおいて、 名前を一括して変換したいと思い、以下のようなNameConv.batというバッチスクリプトを作成しました。 ____________________________________________________________ @echo off for /f "delims=" %%a in ('dir /b !opt!') do ( for /f "usebackq delims=" %%b in (`echo %%a^| sed -e "s/%~1/%~2/g"`) do ( move /y "%%a" "%%b" 1>nul 2>nul if not "%%a"=="%%b" echo 「%%a」→「%%b」 ) ) ____________________________________________________________ このバッチスクリプトを NameConv.bat " " "_" の様にして呼び出すと上手く行きました。 (この場合は、カレントディレクトリの全てのディレクトリとフォルダの名前において、 スペースがアンダーバーに変換されました。) ところが、 NameConv.bat "スペース" " " のように、第一引数に変換文字列に2バイト文字を使用すると、 以下のようなエラーメッセージが出て上手く行きませんでした。 sed: -e expression #1, char 14: Unterminated `s' command どうやら、 echo %%a| sed -e "s/スペース/ /g" といったコードは、上手く行かなかったようです。 そこで、この問題を解決しようと、以下のようなNameRep.plというPerlスクリプトを作成しました。 ____________________________________________________________ #日本語を扱うために必要な設定 use encoding "cp932"; use open ":encoding(cp932)"; use open ":std"; map{ binmode($_,":crlf"); } qw/STDIN STDOUT STDERR/; #置換操作 $name="$ARGV[0]"; $name =~ s/$ARGV[1]/$ARGV[2]/g; print "$name"; ____________________________________________________________ そしてこのスクリプトを for /f "delims=" %a in ('dir /b') do ( @perl NameRep.pl "%a" "スペース" "_" ) の様にしてコマンドラインから呼び出すことで、「スペース」という文字列が、 きちんと処理できるかを試したところ、以下のようなエラーメッセージが出ました。 Unmatched [ in regex; marked by <-- HERE in m/\x{00d8}\x{00f9}\x{005b} <-- HERE \x{00d8}/ at C:\Users\kei\NameRep.pl line 11. どうやら $name =~ s/$ARGV[1]/$ARGV[2]/g; の部分で、$nameや$ARGV[1]に2バイト文字が含まれていると、上手く行かないようです。 #日本語を扱うために必要な設定 以下のコードブロックで、シフトJISに対応できるはず(少なくとも今までは問題なく扱えました) なのですが、何故か上手く行きません。 そこで、sedコマンドやperl、特にperlにおいて、シフトJISコードでの2バイト文字の扱い方を御存じの方に、何かアドバイスを頂きたいと考えています。 長くなりましたが、どうぞよろしくお願い致します。

    • ベストアンサー
    • Perl
  • sedでカンマ区切りの列の置換を行いたい

    以下の様なファイルがあります。 sedコマンドを使用して、カンマで区切られたn番目のカラム目を 置換したい場合どうすればよいでしょうか。 "1","2","3","4","5","6" "1234","12","34567","abcd","efg","hi" "a c","d f","12 34","0","AAA","" "g i","j l","45 67","0","BBB","2021" "m o","p r","3 2 1","1","ABC","" "123","456","","abc","efg","hij" ①1カラム目以外置換(1カラム目以降削除) sed 's/\(.*\),.*,.*,.*,.*,.*/\1/g' test.csv ②最後の6カラム目以外置換(6カラム目以外削除) sed 's/.*,.*,.*,.*,.*,\(.*\)/\1/g' test.csv ③3カラム目を置換(3カラム目を「""」だけにしたい) sed -e 's/\(.*\),\(.*\),.*,\(.*\),\(.*\),\(.*\)/\1,\2,"",\3,\4,\5/g' test.csv とできたのですが、 表現がないというか、置換対象文字列の条件、表現が長いというか、全カラムを指定しているので、 少し、短くできないものでしょうか。 ①パターン sed 's/\([^,]*\),.*/\1/g' test.csv ②パターン sed "s/.*,\([^,]*\)$/\1/g" test.csv の様にできました。 ③パターン 思いう浮かばず これで、できているので間違いはないかとおもいますが、 どうなのでしょうか。 なにかいい案はないでしょうか?

  • 特殊文字の数を調べる

    ファイルの中から、特殊文字(フォームフィード"x0c")がいくつ存在するかを調べたいのですが、上手くとれません。 ファイル容量が大きいため、効率良く調べたいのですが、下記の様にはき出した出力ファイルの長さを調べたのですが、出力には改行(x0a)も含まれてしまいます。 sed -e 's/[^\f]//g' text.in > text.out sed -e 's/[^\014]//g' test.txt > text.out sed以外でも良いので、shellなどを利用し解決する方法をお教え頂けませんでしょうか。よろしくお願いいたします。

  • sed コマンドについて

    はじめまして 当方、初心者で勉強の身です。ご回答頂けたら幸いです。 linuxのシェルファイルが100以上あり、こちらの全ファイル内に含まれる文字列"ABCDE"を文字列"12345"に置換をしたいと思っています。 sed コマンドで sed -e "s/ABCDE/12345/g" *.csh のように実行しても、画面上に変換後が表示されるだけで その後、ファイルを見ても置換されていません。 どのようにすれば、全ファイルが修正されるのでしょうか。 以上です。回答の方をよろしくお願い致します。

  • sedで「(~)」を使って文字列の一部を取り出し

    sedで「(~)」を使って、文字列の一部を取り出したいのですが期待した結果になりません。 以下のようなファイルがあります。 そこから、最初に見つかった「A-Z0-9」を含む文字列を取り出したいのですが、 どうしても、2番目にでてくる「0-9」でなる文字列が取り出されます。 環境は、Solaris/Linuxになります。 ■ファイル cat aaa "aaa","bbb","ccc","123456","ddd","eee","fff,"0000","ggg" "aaa","bbb","ccc","AAA123","ddd","eee","fff,"0000","ggg" ■sed sed 's/.*,"\([A-Z0-9].*[0-9]\)",.*$/\1/g' aaa ■結果 0000 0000 期待する結果は、 123456 AAA123 なのですが、 期待した結果を取り出すにはどうしたらよいのでしょうか。

  • sedなどで、特定の文字列内の数値を抽出したい

    sedなどで、特定の文字列内の数値を抽出したい シェルスクリプト内で、sedなどを使って特定の文字列内の文字列を抽出したいのですが、どうすればいいでしょうか? たとえば、job 999 at 2016-09-28 00:00のなかから、job ~ at内の「999」を抜き出したいです。 echo job 999 at 2016-09-28 00:00 | sed -e 's///g'... のようにして実行させたいです。