• ベストアンサー
  • 暇なときにでも

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

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

共感・応援の気持ちを伝えよう!

  • 回答数4
  • 閲覧数3778
  • ありがとう数5

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

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

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

共感・感謝の気持ちを伝えよう!

質問者からのお礼

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

関連するQ&A

  • 正規表現、置換について

    ファイルから読み込んだ行データを置換したいのですが どういう正規表現にすればよいかご教示下さい。 【置換対象】 testをXXXにしたい ただし、文字列中の後方一つ目のみを置換したい。 【データ】 c:/test/ctestab → c:/test/cXXXab c:/testctest → c:/testcXXX c:/testtesta → c:/testXXXa c:/testtest → c:/testXXX c:/test → c:/XXX

  • 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 よろしくお願いします。

  • 正規表現の後方参照

    PHPにおいての、正規表現の後方参照について教えて下さい。 aaaaa ( (pattern1)(pattern2)(pattern3) )bbbbb このような正規表現において、pattern1=$1、$pattern2=$2、pattern3=$3ですが、 外側のカッコ全体を参照する方法はありますでしょうか? よろしくお願いします。

    • ベストアンサー
    • PHP

その他の回答 (3)

  • 回答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自体にしても バージョンによって拡張されている範囲に違いがあったり、 独自の拡張が加えられていたりするので使うときには注意が必要です。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

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

  • 回答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フラグもいらないんじゃ?

共感・感謝の気持ちを伝えよう!

質問者からのお礼

ありがとうございます。 得たい結果を得ることができました。 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の正規表現の表記が特殊ということでしょうか?

  • 回答No.1

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

共感・感謝の気持ちを伝えよう!

質問者からのお礼

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

関連するQ&A

  • [awk]2つのファイルを参照して1つのファイルに出力する方法

    最近プログラミング(シェル、awk)を始めた者です。 かなり大まかなものは作れるようになったのですが、急遽、大規模なデータ整理を行わないといけなくなってしまったため、皆さんの知恵を貸していただきたく質問いたしましたm(_ _)m 以下に示すような2つのファイルがあります。 (file1)         (file2) 1 6           1  1  2  10 11 2 3           2  3  5  7  8 3 5           3  6  2  12 13 4 1           4  9  4  5  19 5 2           5  10 19 1  5 6 4           6  4  8  2  9 file1を上から1行ずつ順に読んでいき、2列目の値と同じものをfile2の1列目から探します。合致したところで、file2の合致した行の2列目以降を行番号を付けて表示するというものです。 (「file1の2列目の値=file2の1列目の値」を探し、file2の合致行の値を出力。) 上記ファイルですと、結果的に 1  4  8  2  9 2  6  2  12 13 3  10 19 1  5 4  1  2  10 11 5  3  5  7  8 6  9  4  5  19 という具合になります。 2つのファイルの行数は同じではなく、また、両ファイルとも1列目が行番号というだけで、他の列の値に規則性はありません。 file2の行数は100万以上の大規模なものになります。 自分が作ったものを掲載できればよかったのですが、あいにく会社のPC内にありまして、持ち出しできないため、掲載できません。 動作環境はLinux(RedHat)になります。 他のプログラミング言語についてはまだ分からないため、awkもしくはシェルでお願いいたします。

  • sedの-iオプション

    man sedで探したのですが-iオプションの説明がありません。 実際sed -iで動かしてみると自ファイルを更新できました。 LINUX上で-iオプションの説明を参照するにはどうすればよいでしょうか?

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

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

  • sedの正規表現について

    下記のsedコマンド正規表現の意味がわかりません どのような動きをしているのか教えて下さいm(__)m $ file_name="linux.txt" $ echo $file_name | sed -e "s/.*\.\([^.]*\)\$/\1/g" txt

  • 正規表現について(sed)

    いつもお世話になっております。 下記のようなURLから、特定のパラメータ以外はすべて除去したいのです。 http://XXX.jsp?rank=6&uid=aaaabfadfddfd&k=open&serial=12345&pr=ABC 残したいパラメータは k= a= pr= です。 s/[&?]\([k]\|[a]\|[pr]\\)=[0-9a-zA-Z%_-]\+//g この表現で、なんとか残したいパラメータを除去するのはできました。 「これ以外」という表現ができれば、望みの結果になると思うのですが、 いろいろ試してもうまくいきませんでした。 そもそも考え方が違うのかもしれないですが。。。 申し訳ありませんが、お詳しい方教えていただけると非常に助かります。 よろしくお願いいたします。 すみません、先ほどPHPでの処理でどうにかならないかと思い、 別の似たような質問を投稿してしまいました。 今回はLinuxのsedコマンドでの処理になるので、あえて別の投稿させていただいています。 申し訳ありません。。。 正規表現について(preg_replace) http://okwave.jp/qa/q7125468.html

  • cshのsed

    ヤマトです。 cshのsedについて質問します。 環境はRed Had Linux7.2です。 文字列置換でsedを使っています。 置換文字列に'/'が入ってしまう場合正常に動作しません。 原因は分かります。'/'が多いって事ですよね(曖昧な言い方ですみません) どのようにしたら、できるでしょうか? 以下に、サンプルを書きます。 ====SAMPLE.sh(一部抜粋)==== set DATA_DIR = /home/hoge set FILE_NAME = hoge.txt sed "s/__DIR__/$DATA_DIR/g" < FILE_NAME > FILE_NAME.sed ====hoge.txt==== 置換した ディレクトリは __DIR__/です ====hoge.txt.sed(作成したいファイル)==== 置換した ディレクトリは /home/hoge/です どのようにsedしたら良いのでしょうか? 教えて頂けると有り難く思います。宜しくお願いします。

  • awk 正規表現を使って置換

    あるファイルの中の2列目に含まれる "ab" "ac" "ae" という文字列をそれぞれ "zb" "zc" "ze"に置き換えたいのですが、awkまたはsedで正規表現を使って効率のいい方法はないでしょうか。 awk ' { gsub(/ab/,"zb",$2); gsub(/ac/,"zc",$2); gsub(/ae/,"ze",$2); print }' testfile でやりたいことはできるのですが、「aの後にb,c,eが続く場合にaをzに置換する」というアイディアを使えばもっと効率のよいスクリプトが書けるはず、と思いつつ、awkの勉強を始めたばかりでなかなか思い浮かびません。 testfileの中身は以下の通り: abcde abaab aaaae acbec accee adabd dceba aeecs hhhgf sbacc 以下のような出力を望んでいます: abcde zbazb aaaae zcbec accee adzbd dceba zeecs hhhgf sbzcc awk ' BEGIN { var = "[bce]" } { gsub("a"var,"z"var,$2); print }' だと "zb" "zc" "ze"ではなくすべて"z[bce]"に置き換わってしまうし、 awk ' BEGIN { var = "[bce]" } { gsub("a"var,"z&",$2); print }' だと"zab" "zac" "zae"になってしまうし… まずはawk,sedで勉強したいと思っていますが、それ以外でもいい案がありましたら教えてください。よろしくお願いします。

  • Perlを使った正規表現について

    テキストファイルを読み込んで、以下のルールに従った文字列だけを.txtで出力するプログラムを書いています。 具体的にはテキストファイル中の "text":"★★★","to_user" で囲まれている★★★の部分のみを抽出したいです。 そこで正規表現に触りだしたのですが、表現がうまくいっていないようで1週間ほどはまっています。。うまく出力できるように直しをいただけないでしょうか。 打ち明けてしまうと、★★★の部分はtwitterの呟き(日本語)になります。 以下がそのソースになります。よろしくお願いします。 print "Input file name: "; $ifname = <STDIN>; open(IN, $ifname); open(OUT, "> out.txt"); #出力ファイル while(<IN>){ if($ifname =" m/"test":(.*?),"to_user"/; next if($_ eq ""); print OUT "$_\n"; #書き出し } close(OUT); close(IN);

    • ベストアンサー
    • Perl
  • sed コマンド

    sedを使って、行の中の単語を修正しようとしています。うまくいきません。サジェスチョンをお願いできますか? やりたいこと:  (tab) xxxxx01 (tab) --->(tab) xxxxx01_aaa (tab) (tab) xxxxx02 (tab) --->(tab) xxxxx02_aaa (tab) (tab) xxxxx03 (tab) --->(tab) xxxxx03_aaa (tab) sed -e 's/ xxxxx0(\d) / xxxxx0\1_aaa /' file.txt > file2.txt エラーメッセージは、\1の参照が適当ではない、と言うものです。 宜しくお願い致します。

  • sedコマンドを使用して、文字の置換を行いのですが助けてください。

    sedコマンドを使用して、文字の置換を行いのですが助けてください。 sedコマンドやawkコマンドなどを使って、aliasesファイルの置換を行いたいのですが、 うまくいかないので教えていただけないでしょうか? 知りたいのは、次のような置換を一括で行うことのできるコマンドです。 ■置換前のファイル ================= AAAA:  :include:/file/name BBBB:  :include:/file/name CCCC:  :include:/file/name ================= ■置換後のファイル(希望する置換結果) ※1フィールド目の任意の文字列をメールアドレスのローカルパートとして利用したい ================= AAAA:  AAAA@example.com BBBB:  BBBB@example.com CCCC:  CCCC@example.com ================= 以上です。