キーワードパターンの抽出

このQ&Aのポイント
  • linuxのコマンドを使用して、あるキーワードから次のキーワードまでの文章を抜き出す方法について教えてください。
  • キーワードパターンに基づいて、文章から特定のキーワードを抽出する方法を知りたいです。linuxのコマンドを使用して実現することは可能でしょうか?
  • キーワードパターンを指定して文章から必要な部分を抽出する方法について教えてください。linuxのコマンドを活用した方法が知りたいです。
回答を見る
  • ベストアンサー

キーワードパターンの抽出

あるキーワードから次のキーワードまでを文章を抜き出し、ファイルへ書き込みたいのですが、 linuxのコマンドでできますでしょうか? 例 --------- キーワード1 --------- 文字や数字・・・・・・・・ ・・・・・・・・・・・・・・・・・・ ・・・・・・・・・・・・・・・・・・ --------- キーワード2 --------- 文字や数字・・・・・・・・ ・・・・・・・・・・・・・・・・・・ ・・・・・・・・・・・・・・・・・・ --------- キーワード3 --------- 文字や数字・・・・・・・・ ・・・・・・・・・・・・・・・・・・ ・・・・・・・・・・・・・・・・・・ からキーワード1とキーワード3を抽出したい場合 --------- キーワード1 --------- 文字や数字・・・・・・・・ ・・・・・・・・・・・・・・・・・・ ・・・・・・・・・・・・・・・・・・ --------- キーワード3 --------- 文字や数字・・・・・・・・ ・・・・・・・・・・・・・・・・・・ ・・・・・・・・・・・・・・・・・・ などと抜き出されるようにしたい。

  • devid
  • お礼率34% (166/478)

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

  • ベストアンサー
回答No.4

#1です。 > 難しいです。t(if・・・について > このような書き方は始めてみました。awk以外でも書くのでしょうか? awk特有の文法なので、awk以外では、例えばLispのcond特殊形式が似た記法をするくらいで、あまりお目にかかれません。丸カッコではなく波カッコであることに注意。 > tが否定のときは以下のif処理を飛ばすといういみでしょうか? 考え方は合っています。 > tはブーリアン型?if (t=true) {if・・・}というイメージでしょうか? 概ねそのイメージであっていますが、awkを含め古代の言語にはブーリアン型というものが存在しないことが多いです。例えば、今でもかろうじて生き残っているC、Fortran、Basicの3つの言語は、最初発表された時にはブーリアン型に相当するものがありませんでした。awkの場合には、基本型として数値型と文字列型が存在します。 そして、そのような言語で論理値(真偽値)を表す場合、0等を偽、それ以外を真とみなすことが通例となっていて、awkでもそのように、0と長さ0の文字列を偽、それ以外を真とみなすようになっています。 http://gauc.no-ip.org/awk-users-jp/blis.cgi/DoukakuAWK_165 > !t&&s{print$0}について > tが否定でsは1のときに以下実行? > 因みに!t&&sのsはなぜ0以外で正の意味になるのですか? tが偽(0)でsが真(非0)の時にprint$0を実行、で合ってます。 上にも書きましたが、0以外の値が真であるとみなされるので、そのようになります。

devid
質問者

お礼

解説まで有難うございます。大変参考になりました。

その他の回答 (4)

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

考え方の一つです。 区切り キーワード(1行) 区切り 本文(複数行) となっているので、 t : 現在の行がキーワードと本文のどちらか?と示す変数 s: 現在のブロックが表示対応キーワードのものかを示す変数 という変数を用意すると (初期t=0,s=0) 区切り : t=0からt=1へ : 出力するかどうかは下のキーワード次第 キーワード(1行) : t=1 : 該当キーワードならs=1にして出力/ そうでないならs=0 区切り : t=1からt=0へ : s=1なら出力 本文(複数行) : t=0: s=1なら出力 (次の)区切り : t=0からt=1へ: 出力するかどうかは下のキーワード次第 ... となります。このt,sに注目して、それぞれの処理を分岐すると、#2さんのawkスクリプトみたいになります。 さて。 キーワードが日本語の場合、この方法ではうまく動作しない可能性もあります。 その場合は、マルチバイトに対応した言語を使いましょう。 awkのスクリプトですが、標準の文法は次の通りです 条件1 { 処理1 } 条件2 { 処理2 } 条件3 { 処理3 } ... これは、他の言語流に書けば if (条件1) { 処理1 } if (条件2) { 処理2 } if (条件3) { 処理3 } ... です。他の言語に移植するさいには、参考にしてください。

devid
質問者

お礼

有難うございます。参考にさせて頂きます。

回答No.3

再び#1です。解説が必要なくらい面倒くさいコードに対する解説を行います。 主に awk '/^-+$/{t=!t} t{if($0~/キーワード1|キーワード3/){print"---------";print$0;s=1}else{s=0}} !t&&s{print$0}' の部分の解説です。awkは、1行づつ読み込む度に指定されたプログラムを実行する、というプログラムです。少し複雑なテキスト処理に好んで用いられました(Perl等に殆ど置き換えられましたが)。 前提として、$0には今読み込まれた行の内容が格納されており、その他の変数は全て0等(型にもよる)の値で初期化されます。 また、中括弧の直前の式や正規表現は、その中括弧が実行される条件を示しています。 詳しくは $ man awk とするか、「man awk」でググって下さい。 /^-+$/{t=!t} キーワード部が---------で始まり、同じく---------で終わることから、「その行が'-'だけで構成されている場合は、tの値をトグルする(tにtの否定を代入する)」という処理を行い、今からキーワードの判定を行うのか、それとも判定が既に行われていて(その結果はsに代入されている)、あとは適宜出力するだけなのかを選択することにしました。 問題ないかと思いますが、/から/で囲まれた正規表現については、最初の^は行頭を、最後の$は行末を、-は文字-を、+は直前の文字(ここでは-)が1回以上続くことを意味しています。 t{if($0~/キーワード1|キーワード3/){print"---------";print$0;s=1}else{s=0}} この行はキーワードあたり2度実行されます。1度目は---------だけの行、2度目はキーワードが書かれた行です。その直後の---------の行は、この部分が実行される直前にtが偽に戻ってしまうため、この部分は実行されないことになります。 現在キーワード部に差し掛かっている場合(tが真の場合)、今読み込まれた行($0)がキーワード等と一致するかどうかを判定し、もしも一致する場合には、直前の行の内容であろう---------を出力した後、キーワード(=今読み込まれた行=$0)を出力し、ここからは暫く出力し続ける事を示すための変数sに1を代入しておきます。キーワードと一致しない場合には、sに0を代入しておき、暫く出力しない事を意味させます。 !t&&s{print$0} !t&&sという事で、現在キーワード部ではなく、かつ、選択されたキーワードに対応するデータの部分である場合に、今読み込まれた行を出力します。 というような構成になっています。 今思えば2個目の正規表現は/キーワード1|キーワード3/よりも/^(キーワード1|キーワード3)$/の方が事故が少ないかも知れません。

devid
質問者

補足

難しいです。t(if・・・について このような書き方は始めてみました。awk以外でも書くのでしょうか?tが否定のときは以下のif処理を飛ばすといういみでしょうか?tはブーリアン型?if (t=true) {if・・・}というイメージでしょうか? !t&&s{print$0}について tが否定でsは1のときに以下実行? 因みに!t&&sのsはなぜ0以外で正の意味になるのですか?

回答No.2

#1です。「ちょっと難しい」と言ったとおり、やり方はあります。 私ならawkを使って、 $ cat ファイル名 | awk '/^-+$/{t=!t} t{if($0~/キーワード1|キーワード3/){print"---------";print$0;s=1}else{s=0}} !t&&s{print$0}' とします。急ごしらえなのでちょっと稚拙ですが。 この場合、「文字や数字」の部分に、-だけからなる行があるとうまく動きません。ただのデータなのかキーワードが間に入るのか判別できないので。

devid
質問者

補足

すみません、わかりません、解説お願いします・・。 全体で3つの{}になっているようですが、{t=!t} t{if~..} !t&&s{} t=!tとは等しくないことだと思いますがtやsは何を表しているのでしょうか?

回答No.1

抽出と言えばgrepですが、その形式だとちょっと面倒です。 行単位のデータに出来るのであれば、つまり入力を キーワード1 データ キーワード2 データ キーワード3 データ ・・・ という形式にできるのであれば、 $ egrep ファイル名 -e '^(キーワード1|キーワード3)' で行けるんですが・・・

devid
質問者

補足

データはランダムで、特定できません。 linuxは無理?

関連するQ&A

  • テキストを部分ごとに抽出できるソフト

    あるキーワードから次のキーワードまでを文章を抜き出し、ファイルへ書き込みたいのですが、 どのようにすればいいのか分りません。 例 --------- キーワード1 --------- 文字や数字・・・・・・・・ ・・・・・・・・・・・・・・・・・・ ・・・・・・・・・・・・・・・・・・ --------- キーワード2 --------- 文字や数字・・・・・・・・ ・・・・・・・・・・・・・・・・・・ ・・・・・・・・・・・・・・・・・・ --------- キーワード3 --------- 文字や数字・・・・・・・・ ・・・・・・・・・・・・・・・・・・ ・・・・・・・・・・・・・・・・・・ からキーワード1とキーワード3を抽出したい場合 --------- キーワード1 --------- 文字や数字・・・・・・・・ ・・・・・・・・・・・・・・・・・・ ・・・・・・・・・・・・・・・・・・ --------- キーワード3 --------- 文字や数字・・・・・・・・ ・・・・・・・・・・・・・・・・・・ ・・・・・・・・・・・・・・・・・・ などと抜き出されるようにしたい。 このようなことができるフリーソフトご存じないでしょうか?

  • キーワード抽出がうまくいかない

    自然文からキーワード抽出する機能をもつWebページを作ろうと思い、 Lingua::JA::Summarizeを用いて、下記のようなプログラムを書きました。 コマンドライン上から実行したときはキーワードを抽出してくれたのですが、 サーバを立ち上げ、WEBブラウザ上からアクセスしても キーワード抽出(@keywordsが空)してくれません。 他のCGIスクリプトは動いているので、apacheあたりの設定ではないような気がします。 一体、何が原因で、どう対処したらいいのでしょうか? #!/usr/bin/perl use strict; use Lingua::JA::Summarize; print "Content-type: text/html; charset=utf-8\n\n"; #キーワード抽出 my $text = '兄貴たちの晩餐'; my $s = Lingua::JA::Summarize->new({ charset => 'utf8',mecab_charset => 'utf8',default_cost => 1.8, singlechar_factor => 0.2,}); $s->analyze($text); my @keywords = $s->keywords({threshold=>4, maxwords=>10, minwords=>3}); #キーワードの表示 print join(' ', @keywords), "\n";

  • エクセルの文字列を抽出する関数を教えてください!

    テキストファイルから文字列をエクセルに貼りつけ、ある条件の単語のみを抽出する関数について教えてください。 (1)あらゆる文字・記号で構成されている文章のうち、” ”(二重引用符)で囲まれた中のその文字列だけを抽出するには、どのような関数があるのでしょうか。 (2)ある文章は、 (文字数はバラバラの文章).1-文章.doc、 (文字数はバラバラの文章).2-文章.doc、  ・・・ となっているテキストがあるのですが、そのテキストのうち、「数字ー」の形式は同じなのですが、その「(数字)‐」以降「.doc」までの文章のみ抽出するには、どのような関数になるのでしょうか。 マクロは組めませんので、関数で教えて頂ければ幸いです。 宜しくお願いします。

  • エクセルでキーワードを入力し、抽出・貼付する方法

    質問初心者なので説明が足りなかったらすみません。 エクセルで「データベース」sheetからキーワードを含む行を全て「抽出」sheetに貼り付けるというマクロを組みたいのですが、どうもうまくいきません。 (1)「抽出」sheetにキーワードを入力。   (例) ベーコン (2)「データベース」sheetから抽出。   (例) 日付      項目         内容    1  2014/5/3  冷凍食品  ほうれん草とベーコンのバター炒め    2  2014/5/8  冷凍食品  牛肉コロッケ    3  2014/5/20  加工食品  2/1ベーコン(4枚入り)    ※ 「ベーコン」と記載される行を全て抽出したい。つまり、1・3行。 (3)抽出した行を「抽出」sheetに値貼付。 上記のようにしたいのですが、私の知識では分からなかったので、分かる方がいれば教えてください。 ちなみに私はCountifで挑戦していたのですが、できるのでしょうか?     

  • EXCELでの抽出について

    セルに数字を入力したものから、指定の数字を含むセルを抽出する方法を教えてください。 オートフィルのオプションで試してもうまくいきません。 例:123、234、345、456 の数字それぞれのセルで、うち下1けた3と5を抽出したい場合→123、345が抽出される また、よい関数があるのでしょうか。 教えてください。

  • [初心者]perlで文字列抽出

    perlの超初心者です. 標準出力された文字の中から任意の文字列をperlで抽出したいのですが... 例えば, 1 lsコマンドでファイル一覧を表示 2 表示された中から任意の文字列とマッチするものを抽出 3 マッチした文字列の後ろの文字を知る(拡張子とか) 4 さらに,1~3を'perl hoge.pl'とコマンド打つだけのワンアクションでやりたい. という感じなのですが... 勉強を始めたばかりなので,どういったキーワードを勉強すればよいのか,見当つかない状態です... おそらく,私がしょうもない質問をしているのだろうとは思いますが, 何かヒントでも教えていただければ幸いです. 周りに詳しい人物もいないので,なんとか頑張って習得したいと思っています. よろしくお願いしますm(><)m

    • ベストアンサー
    • Perl
  • 出現順にソートしてくれるキーワード抽出ツール

    キーワードの抽出ツールを探しているのですが、 抽出されたキーワードを出現順にソートしてくれるものはないでしょうか。 例えば、上の2行を処理した場合 「キーワード 抽出ツール 探している 抽出された 出現順 ・ ・ ・」 といった感じです。 ウェブにある「専門用語自動抽出システム」や「TermExtractor」、「EKwords」、「用語Ex」などでは、出現順のソートが出来ませんでした。 もし該当するソフト・ツールをご存じでしたらご教授ください。 動作環境:Windows 7、シェア可

  • 正規表現にマッチした文字列の抽出

    閲覧頂きありがとうございます。 Linuxのsedコマンドに該当するwindowsコマンドは存在しますでしょうか? 存在しない場合、batやマクロでの長い記述となってしまっても構いません。 検索で調べたところ、特定のdllを入れればsedを使用できるとあったのですが、その方法は取りたくありません。 100万行以上あるテキストファイル(一行=一レコード)の中から、正規表現とマッチする文字列の抽出作業です。 1行に1つ、不特定な場所にその文字列が存在するという形です。 その抽出した文字列を、別のテキストファイルへ吐き出す…といった処理を想定しています。 どうかご教示いただけると幸いです。 環境 windows7、EmEditor使用

  • キーワードをファイル内容で検索したい

    Linuxにおいても、Windowsの[検索]->[ファイルに含まれる単語または句]のように、ファイルの中身をキーワードで検索して、そのファイル名を表示するようにしたいのですが、コマンドやスクリプトが分りません。 スクリプトを作るとしたら、cat と grepを用いるのであろうということは分るのですが・・・ RedHat Enterprise WS4ではGUIの検索では内容検索が出来るのですが、コマンドラインから検索したいので。

  • 「認証用キーワード」

    ブログのコメントを入力すると「認証用キーワード」で"画像に書かれた文字数字を入力して下さい"と言う入力画面が出る場合があります。 これは何のためですか??