[awk]マッチしたものをすべて取り出す方法とは?

このQ&Aのポイント
  • awk(GNU awk)を使って正規表現にマッチした部分文字列を最初にマッチしたものだけでなく、すべて取り出す方法を教えてください。
  • grepコマンドを使うと、簡単にマッチした部分文字列を取得できますが、awkだけで実現する方法はありますか?
  • 現在の環境はGNU Awk 4.0.1です。
回答を見る
  • ベストアンサー

[awk]マッチしたものをすべて取り出したい

awk(GNU awk)を使って正規表現にマッチした部分文字列を最初にマッチしたものだけでなく、すべて取り出したいと思っています。 grepコマンドを使うと次のように簡単に取得できるのですが、awkだけで実現する場合どのように記述したらよいのでしょうか? ■例 $ echo 'abcdebx' | grep -o 'b.' 結果: bc bx # 最初にマッチしたものだけなら取得できる $ echo 'abcdebx' | awk 'match($0, /b./) {print substr($0, RSTART, RLENGTH)}' 結果: bc ■環境 GNU Awk 4.0.1 よろしくお願いします。

noname#241088
noname#241088

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

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4848/10261)
回答No.1

ループするしか無いと思います。 awk '{while(match($0,/b./)){print substr($0,RSTART,RLENGTH);$0=substr($0,RSTART+RLENGTH)}}'

noname#241088
質問者

お礼

notnotさん いつもありがとうございます。 提示して頂いたコードで実行できることを確認しました。 どうもありがとうございました。

関連するQ&A

  • grepでのグルーピングの扱いについて

    複数のグルーピングされた正規表現にマッチする文字列を取り出したいと思っています。 GNU awkコマンドではできるようですが、grepコマンドだけでも可能でしょうか? ■例 # 対象文字列: str="bash dash zsh" # 正規表現: re="([^ ]).+[ ]([^ ]).+[ ]([^ ]).+" # 欲しい結果(グルーピングされた正規表現にマッチする文字列) 1番目のグルーピングに対して: b 2番目のグルーピングに対して: d 3番目のグルーピングに対して: z ■環境 $ grep --version grep (GNU grep) 2.16 よろしくお願いします。

  • preg_matchのキャプチャ用サブパターンにマッチした文字列について

    お世話になります preg_matchのキャプチャ用サブパターンにマッチした文字列について 意図した動作が、試行錯誤しても全く得られませんので 分かる方にお教えいただきたく存じます 条件1 [*DATA: *]で囲まれたデータ(以下DATA)を取得 条件2 DATAにはoXoまたはoYoが順不同で、それぞれ1回または0回出現する $test = '[*DATA: A oYo B oXo C *]'; $reg = '/\[\*DATA:(.*?)(oXo|oYo)(.*?)(oXo|oYo)?(.*?)\*\]/u'; preg_match($reg,$test,$match); $matchの結果 $match[0] => [*DATA: A xYx B xXx C *] $match[1] => A $match[2] => oYo $match[3] => $match[4] => $match[5] => B oXo C 期待した結果 $match[0] => [*DATA: A oYo B oXo C *] $match[1] => A $match[2] => oYo $match[3] => B $match[4] => oXo $match[5] => C 1回または0回を表す「(oXo|oYo)?」が「0回」という条件が先に評価されてしまっているようなのですが「1回」を先にするすべはあるのでしょうか? 「(oXo|oYo)?」を「(oXo|oYo)」にすると期待した結果になりますが、条件2の「oXoが0回」「oYoが1回」出現した場合マッチしなくなります。 識者の方、お忙しい中恐縮ですがご教授いただけたらうれしいです。

    • ベストアンサー
    • PHP
  • grepにマッチした正規表現の文字列を取得したい

    grepにマッチした正規表現の文字列を取得し、マッチした文字列を 一覧で取得したいのですが、方法がわかりません。 ※例 grep [0-9][0-9][0-9][0-9][0-9] 検索ファイル名 > 出力ファイル名 不明点あればお知らせください。 よろしくお願いします。

  • grepの正規表現での最短マッチが効かない

    echo 'abcd_efg_hijk_l_m_n_opqr' | grep -o -E "^[a-z].+?_" 上記の結果が、期待する abcd_ になりません。 なぜか、 abcd_efg_hijk_l_m_n_ になります。 egrepでも同じでした。 phpでのpreg系ではabcd_をマッチ結果として返してきます。 linuxのgrepでこのような結果になるのはなぜですか? よろしくお願いします。

  • awk等で特定文字列の抜き出し

    次のような文字列から特定の文字を抽出したいです。 「xxx,yyyyy,zz」 で、yyyyの部分のみをコマンドラインから抽出したいのですがどのようにしたらよいでしょうか? ためしに自分で考えたコマンドは以下の通りです。 % echo "xxx,yyyyy,zz" | awk '{print substr($0, 1, index($0, ","))}' で行うと最初の「,」でなりxしか抽出できません。 すみませんが、いい方法がありましたら教えて下さい。

  • Bシェルのawkコマンドについて

    Bシェルのawkコマンドについてですが、例えばプロンプトから % ls -l hoge.txt | awk '{print $5}' と入力すると、hoge.txtのファイルサイズが出力されますが、同様のことをBシェルの中で行おうと思っています。 下記のように、配列arrayにはスペース区切りで3つのデータが入っており、N番目のデータを取得したいという場合に、Nに変数を使用して取得する方法がわかりません。 #!/bin/sh array="AA BB CC" num=3 # CCを取得したい echo $array | awk '{print $num}' 上記で実行すると、"AA BB CC"のようにすべて出力されてしまいます。awkで出力する箇所を${数値}で指定すればうまくいくのですが、ランダムで決めた数値(1~3)をnumに入れて取得したい場合、このようなことは可能でしょうか。 もし不可能な場合でも、awk以外に何かコマンドがあればご教授願います。なお、作成するのはBシェルになります。

  • 正規表現の初心者です

    正規表現初心者です。 なぜ、 [0-9]+ という正規表現が下記の112にあたらないのでしょうか? 0-9(数字)の一文字以上の繰り返しなので、複数桁の数字にマッチすると思ったのですが・・。 echo 112|grep -e "[0-9]+" > (マッチせず)

  • preg_matchの正規表現がうまくいかない

    たとえば、http://gehasoku.com/?p=2のソースコードには ------------------- <rdf:Description rdf:about="http://www.com/aaa.html" trackback:ping="http://www.com" dc:title="タイトル" dc:identifier="http://iii.com/bbb.html" dc:subject="ハードウェア" dc:description="1 名前:名無しさん " dc:creator="soft_net" dc:date="2012-02-21T20:05:01+09:00" /> ------------------- のような形の<rdf:Description~~~/>タグの情報ががいくつかあると思います。これらすべてを文字列として取得したくて、次のようなphpを作成しましたが、うまく動作しません。 原因はどうやらpreg_match_allの正規表現がうまくいっていないからのようですので、 <rdf:Description~~~/>を抜き出すことができる正規表現を教えてください。 自分でもここでチェックしながらやりましたが、 http://www.rider-n.sakura.ne.jp/regexp/regexp.php <rdf:Description~をマッチすることはできても、/>で閉じることができませんでした。 よろしくお願いします。 <?php $url="http://gehasoku.com/?p=2"; $html=file_get_contents($urls); preg_match_all("/<rdf:Description(.*)?\/>/",$html,$match); print_r($match); foreach($match[1] as $value){ echo $value; } ?>

    • ベストアンサー
    • PHP
  • cshでsubstr

    ヤマトです。 cshの文字列分割について質問します。 環境はRed Had Linux7.2です。 set DATA = A01/B/テスト文字列 のデータの5文字目の文字列は何か取得したいのですが、 substr($DATA,5,1)みたいな書き方は、 awkを使用してできるのでしょうか? ===sample.sh一部抜粋=== set DATA = A01/B/テスト文字列 set AAA = substr($DATA,5,1) ←(?) echo $AAA ===結果=== B 教えて頂けると有り難く思います。宜しくお願いします。

  • preg_matchでのマッチが正しくされない

    メールヘッダを解析して処理させるプログラムを作成しています。 ヘッダから件名を取得するために以下のコードを記述しました。 $head = 'Return-Path: Delivered-To: hoge@hogehoge.com Received: from docomo.ne.jp (mail102.docomo.ne.jp [203.138.203.2]) by www.hogehoge.com (Postfix) with ESMTP id C73904003B for ; Fri, 25 Mar 2011 16:32:19 +0900 (JST) Date: Fri, 25 Mar 2011 16:32:24 +0900 (JST) From: huga@hogehoge.com To: hoge@hogehoge.com Subject: =?iso-2022-jp?B?GyRCJFskMiRbJDIkVSQsJFUkLBsoQg==?=hogehogehugahuga =?iso-2022-jp?B?GyRCJFskMiRbJDIkVSQsJFUkLBsoQg==?= Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-2022-jp" Content-Transfer-Encoding: 7bit X-Virus-Scanned: clamav-milter 0.96.3 at MCN X-Virus-Status: Clean' $ptrn = '/Subject:([\s\t]*=\?iso-2022-jp\?[BQ]\?([^\?]+)\?=)+.* Message\-ID/i'; preg_match($ptrn, $head, $regs); var_dump(regs[0]); $headに別関数で取得したメールのヘッダ情報、$ptrnに正規表現での一致条件を書き出しました。 PHPの正規表現チェッカーでは正常にマッチしたのですが、preg_matchで動作させるとマッチしてくれません。 何がまずいのでしょうか? 正しくマッチさせる方法をご回答お願いします。

    • ベストアンサー
    • PHP