• ベストアンサー

sedで正規表現の後方参照を使いたい。

後方参照の練習をしようとしています。 1111:2222:3333:4444 5555:6666:7777:8888 というファイルを:でフィールドを区切って1列目と2列目を sedをつかってひっくり返そうとしました。 sed 's/^(\d{4}):(\d{4})/^$2:$1/' test.file などいろいろやってみたのですがうまくいきません。 良ければ教えてください。

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

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4845/10256)
回答No.3

伝統的には、grep コマンドでつかうのが「正規表現」、egrep コマンドで使うのが「拡張正規表現」で、Perl等のは拡張正規表現のさらに拡張になってます。 すでに出ているように、( | ) { } 等が文字そのままの意味なのか正規表現の特殊文字なのかの切り替えに \ をつけるかつけないかなどが違います。 ここにまとめられています。 http://www.kt.rim.or.jp/~kbk/regex/regex.html

vivi0303
質問者

お礼

ありがとうございます。正規表現にもいろいろあるのですね。^^

その他の回答 (3)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.4

> これはsedで正規表現を使う場合、記号はエスケープする必要が > あるということでしょうか? > またsedで使える正規表現とperlで使える正規表現がちがうと > 思うのですがperlの正規表現の表記が特殊ということでしょうか? まずはじめに。 #3の方の回答にあるとおり、大きく分けると grep/sed で使われていたもの、 egrep/awk で使われていたもの、perlで使われているもの。の三つになります。 おおまかに古いほうから grep → sed → egrep → awk → perl の順です。 '*'とか'^','$' などを見てもわかるとおり、grep/sedの正規表現でも記号類すべてに'\'を つけなければメタ文字にならないということはありません。 '('とか'{'に'\'が要求されるのは、おそらくCのソースなんかを検索するときに '\'がついていない'('はメタ文字にならないほうが都合がよいからでしょう。 #という話を昔聞いたことがあります その割に '['は違ったりするのですけどね。 egrepは、grep/sedで用いられていたのとは違ったアルゴリズムで正規表現検索を 実現していました。そのため新たな別プログラムになっていたりするのですが、 なぜ '(', '{' の扱いが変わったのかはわかりません。 #Aho博士に訊いてください んでPerl。 POSIXという規格では、grep/sedの受け付ける正規表現を「基本正規表現(Basic Regular Expression)」、 egrep/awkの受け付けるものを「拡張正規表現(Extended Reguar Expression)」 のように分類していますが、実は拡張正規表現は基本正規表現のすべてを含んだものではありません。 斯様にごちゃごちゃしたものがありましたので、Perl3か4の時点でPerlの original autherであるLarry Wallが ・使える正規表現は基本正規表現+拡張正規表現とし ・記号がメタ文字になる場合はそれのみでなるようにし、基本正規表現にあるような'\(' や '\{' という表記は採用しない といった規則のもとでまとめました。 そしてPerl 5でいわゆるPerl拡張が導入されました。 Perl互換の正規表現というと、このPerl 5での拡張をサポートしているかどうか で言われますが、実は言語とかライブラリによってとかPerl自体にしても バージョンによって拡張されている範囲に違いがあったり、 独自の拡張が加えられていたりするので使うときには注意が必要です。

vivi0303
質問者

お礼

ありがとうございます。 詳しくありがとうございました。 よく分かりました。^^

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

> bash-3.2$ sed 's/^\([0-9]+\):\([0-9]+\)/^\2:\1/g' test > 1111:2222:3333:4444 > 5555:6666:7777:8888 > > とやってみたのですが、まだうまくいきません。 あー(笑) sed は + も使えません。 ただし、GNU sed だったら \+ と書くことでPerlの+と 同じ意味にすることができます。 あと、置換パターンの先頭にある ^ は何のために? もうひとつgフラグもいらないんじゃ?

vivi0303
質問者

お礼

ありがとうございます。 得たい結果を得ることができました。 bash-3.2$ sed 's/^\([0-9]\{4\}\):\([0-9]\{4\}\)/\2:\1/' test 2222:1111:3333:4444 6666:5555:7777:8888 これはsedで正規表現を使う場合、記号はエスケープする必要が あるということでしょうか? またsedで使える正規表現とperlで使える正規表現がちがうと 思うのですがperlの正規表現の表記が特殊ということでしょうか?

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

Perlの正規表現を使って書いちゃってますね。 GNU sedの新しいのだとオプション指定でPerl表記の正規表現を 受け付けるようにできますが、ふつーのsedはそんなことはできません。 \d は使えません → [0-9] を使用 後方参照で使うためのカッコは ( ) ではなく \( \) です 回数指定のブレースは、\を前置します。 置換文字列の中で後方参照をするときに使うのは $ ではなく \ です。 あえて答えそのものは書きませんので試してみてください。

vivi0303
質問者

お礼

ありがとうございます。 Perlだけで使える文法だったんですね。 bash-3.2$ sed 's/^\([0-9]+\):\([0-9]+\)/^\2:\1/g' test 1111:2222:3333:4444 5555:6666:7777:8888 とやってみたのですが、まだうまくいきません。 難しいですね。><

関連するQ&A

  • VBScript.RegExp正規表現での後方参照

    VBScript.RegExpを使うと、VBA でも正規表現が使えることを最近知りました。 置換は Replaceメソッドでできるようですが、例えば Perlでの s/(.)(.)/\2\1/; のような置換(後方参照?前方参照?)はどうしたらできるでしょうか?

  • sedでの置換がうまくできません。

    sedを使用して以下の様な文字列を置換したいと考えています。 iPar(\"w\") → 何かの文字列 そこで以下のようなsedスクリプトを作成しました。 s/iPar\(\"w\"\)/test/g  → a.sed 使用してみました。具体的には↓のコマンド >sed -f a.sed inputデータ >outputデータ しかし結果ファイルをみても何も変わってくれません。 なにが悪いのでしょうか? どなたかご指南下さい。

  • WSH(WScriptHost?)の正規表現(後方参照)について

    最近WSHを始めたのですが、文字列の中から10桁の数字を取り出す処理(後方参照?)はどのように書けばよいのでしょうか? str = "ああああ4104715018あああああああ" Set fso = CreateObject("Scripting.FileSystemObject") Set regEx = New RegExp regEx.Pattern = "[0-9]{10}" If regEx.Test(str) Then Set IE = CreateObject("InternetExplorer.Application") IE.Navigate2 "http://www.xxx.xxx.cgi?xxx=" ←ここに数字列を入れたい IE.Visible = True End If ↑とりだした数字列をCGIのパラメータに入れてページを別ウインドウで表示したいのです。 ちなみにPerlだと↓でできるようなのですが…。 $_ = "ああああ4104715018あああああああ"; if( m{([0-9]{10})} ) { print "$1"; } 表示結果 4104715018 よろしくお願いします。

  • SEDの使い方

    こんにちは。 sedである複数行のパターンにマッチしたら置き換えるということをしたいのですが上手くいきません。 たとえば、 test.txt aaa bbb ccc に対して、 sed -i.bak s/aaa/aaa'\n'111/g test とすると、 test.txt aaa 111 bbb ccc となります。 これを戻す方法として、 sed -i.bak s/aaa'\n'111/aaa/g test としても、元に戻りません。 sedを用いで元に戻す方法をご教示いただけないでしょうか。 よろしくお願い致します。

  • ["]でくくられた文字列内に存在する[,]をsedで処理する正規表現について

    PostgreSQLを使うのは初心者です。 csvファイルよりCOPYコマンドを使ってPostgreSQLのテーブルにデータを入れようとしています。 もとになるcsvファイルは、データの区切りは[,]であり、文字列は["]でくくられ、さらに["]でくくられた文字列には[,]が存在します。 <csvデータ例> 123,"aaa","b,cde",234 いろいろ調べてみた結果、COPYコマンドを実行する前に、sedコマンドで正規表現を用いて置換をすればよいとの結論にたどり着いたので、 (1)["]でくくられた文字列内の[,]を[#]に置換する  → [123,"aaa","b,cde",234] => [123,"aaa","b#cde",234] に置換したい (2)["]を除く(sed 's/\"//g')  → [123,"aaa","b#cde",234] => [123,aaa,b#cde,234] に置換したい (3)[,]をtabに置換する(sed 's/,/\t/g')  → [123,aaa,b#cde,234] => [123 aaa b#cde 234] に置換したい (4)[#]を[,]に置換する(sed 's/#/,/g')  → [123 aaa b#cde 234] => [123 aaa b,cde 234] に置換したい を順番に行う処理を考えていますが、(1)で記述する正規表現がわかりません。 正規表現も初めて扱う初心者ですので、色々試してみましたが、うまく置換できません。 どなたかご教授の程をお願いします。 なお環境は、RedHatLinux9 + PostgreSQL-7.4.9です。 以上、宜しくお願い申し上げます。

  • sedを使ってHTMLファイルのタグを置き換えたいのですが、正規表現が

    sedを使ってHTMLファイルのタグを置き換えたいのですが、正規表現が上手く使いこなせなくて困っています。 実際のファイルには、<td class="style1" id="sequence1" >と書かれてある部分があり、これを<td>に置き換えたいのです。 それで、試しに sed -e 's/<td*>/<td>/g' ファイル名 と記述しましたが出来ませんでした。 正規表現の書き方が間違っているとは思うのですが、時間がなくお聞きすることにしました。 正しい書き方を教えて頂けますでしょうか。

  • 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 の様にできました。 ③パターン 思いう浮かばず これで、できているので間違いはないかとおもいますが、 どうなのでしょうか。 なにかいい案はないでしょうか?

  • sedでファイルで条件指定の場合

    スクリプト初心者です。 sedコマンドを使用して文字列の置換をおこないたいのですが、条件がたくさんあるため、 条件部分をシェルのファイルと別ファイルにして実行したいです。 その際、シェル実行時の引数を条件ファイルに入れたいのですが、通常の文字列扱いになってしまい困っています。 アドバイスをお願いいたします。 ・test.sh  find $1 -type f | xargs sed -i -f mypattern.sed ・mypattern.sed  s|${1}aaa|/bbb|g test.sh hoge と実行した場合 "hogeaaa" を "bbb" に置換したいです。

  • sedの使い方

    下記をsedで \" を置換するまたは削除する場合、どのように置換すればよろしいでしょうか。 自分では下記と想定しましたがうまくいきません。 #\"c:\WINDOWS\test.bat\" | sed s/\\\"//g どうかお願いします。

  • sedコマンドに関して

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

専門家に質問してみよう