ウォーターサーバーとコーヒーマシンが一体化した画期的マシン >>

何万行も書いてあるテキストファイルがあります。抽出したい文字列の一覧がテキストファイルにまとめられています(文字列は約1000個)。抽出したい文字列は一行にひとつづつ書かれています。何万行も書いてあるテキストファイルから抽出したい文字列と二つ合致したらその行を抽出したいです。ここで、注意していただきたいのが、抽出したい文字列一覧から二つの文字列にヒットした行を抽出したいです。宜しくお願い致します。



何万行も書いてあるテキストファイル
aaaaa abc edi
bb aert kkkkkkkkkk lllllll
ddddd aaaaa anhi kkk   
・・・・・・・・
・・・・・・・・

抽出したい文字列一覧のテキストファイル
aaaaa
bbbbb
ddddd
iiiiiiiii
eeeee
・・・・・
・・・・・

このQ&Aに関連する最新のQ&A

A 回答 (4件)

> my $str = "(?:.*?(?:$data)){$more_than}";


> の方がちょっとだけいいかも

確かに。
more_than が大きくなるとぜんぜん違ってくるでしょうね。
    • good
    • 0

my $str = "(:?$data)" . ".*(:?$data)" x ( $more_than - 1 );



my $str = "(?:.*?(?:$data)){$more_than}";
の方がちょっとだけいいかも>#2.

いずれにしても, やるべきことから次第に離れていってる感じは否めない.
    • good
    • 0

おもしろそうなので、ANo.1 さんと同じ使い方になるよう書いてみました。


ロジックは違います。

#!/usr/bin/perl
# this.pl more_than looking_list search_targets [...search_targetsN]
use strict;
use warnings;

my $more_than = shift @ARGV;
my $looking_list = shift @ARGV;

my $regex = do {
open my $in, '<', $looking_list or die;
my @data;
while ( my $line = <$in> ) {
chomp $line;
push @data, "\Q$line\E";
}
close $in;
my $data = join '|', @data;
my $str = "(:?$data)" . ".*(:?$data)" x ( $more_than - 1 );
qr{$str}o;
};

while ( defined( my $line = <> ) ) {
chomp $line;
if ( $line =~ /$regex/ ) {
print $line, "\n";
}
}

exit;

もとの質問は ACL 中の IP アドレスの比較ということなので単純な文字列比較でよいのかは疑問です。

例えば 172.16.0.0/12 と 172.16.1.1 や 172.17.0.0/255.255.255.0 は一致している扱いになるはずです。

対象データの一部でも出した方がよい回答がつくのではないでしょうか。
    • good
    • 0

フィルタコマンドだったら何でもよさそうなので、パッと書けるRubyで書いてみました。


https://ideone.com/t5ekY

コマンドラインとして、次のイメージです。

this.rb 2 抽出したい文字列一覧のテキストファイル 何万行も書いてあるテキストファイル

第一引数でn以上を示すので、1へも3へも変えられます。


自分はPerlにぱっと翻訳できないので、必要があれば他の方の回答を待ってください。
そして、なにより貰った回答へちゃんと返信をつけましょう
http://oshiete.goo.ne.jp/qa/6824950.html
同じ件ですよね?
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QPerlで特定行から特定行までを抜き出したい

皆さんのお知恵をお貸し頂ければ幸いです。

Perlで以下のようなことをしたいと考えています。
例えば、次のようなテキストファイルがあったとします。

example.log
==================================
aaaa
hogehoge
test
okok
perl
script
==================================

上記ファイルを読み込んで、「hogehoge」から「perl」の間に挟まれた行だけ抜き出したいのです。
イメージとしては、読み込んだファイルを配列に入れて、一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

このような場合、どういう風にすればいいのでしょうか?
恐れ入りますが、ご教授頂ければ幸いです。

それでは、どうぞよろしくお願い致します。

Aベストアンサー

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $flag = 0 }
  elsif ($flag) { print "$data\n" }
}
close FH;

で、もっと略したいPerlな人だとこんな感じ。Perl独特の記法がふんだんに使われているので、勉強するには不向きかもしれませんが^^;

open FH, "example.log" or die $!;
while (<FH>) {
  print if /^hogehoge$/ .. /^perl$/ and !/^(?:hogehoge|perl)$/;
}
close FH;

※インデントに全角空白を使っているので、コピーする場合はタブなどに置換して下さい。

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $fl...続きを読む

QPerlで別ファイルから文字列の抽出

当方、サーバ管理でインフラ系の経験しかなく、今回はperlでスクリプトの作成に挑戦しておりますがなかなか理解できていません。お知恵をお貸しください。

やりたいこと:
ある入力を受けたら、別ファイルに照会して特定列の文字列を抽出する。以下に例を示します。

入力が gad の場合(小文字です)、file1を参照する。例では一行目にGAD****があるのでこれに該当することとする。最終的にoffice が出力されるようにしたい。


file1の内容:
GAD93911 <test1> office
HOA14845 <test2> desk
ABC52311 <test3> chair
KFI33823 <test4> home

よろしくお願いいたします。

Aベストアンサー

ファイルを開いて、各行を順番に /$in\d+\s<\w+>\s(\w+)/iでマッチするものを取り出して、それを使う・・

Q複数ファイルの読み込みについて

perl初心者です。

あるディレクトリから拡張子がdataであるファイルを全て読み込みたいのですが、方法がわかりません。
cshで書くと
foreach arg (*.data)
コマンド $arg

のようになりますが、perlだと
foreach $arg (@arg){
コマンド $arg

となりますよね?
引数がリストなのでよくわかりません。
そもそもperlではできないのでしょうか?


それともう一点ですが、ファイルオープンするときに
foreachループの中で
open(FILE, "$arg");
とすることは可能ですか?
上の質問と組み合わせて全てのファイルを開いて作業を行いたいので。

説明が下手ですいません。補足しますのでよろしくお願いします。

Aベストアンサー

while(<*.data>)
{
## $_には、*.DATAなファイル名が格納されている。
open(F,"$_"); ##openする。
while(<F>)
{
##読み出された内容が$_に格納されている。
print $_; ##出力してみる。
}
}

というのが最短コーディングです。

Qディレクトリ名を取得したい

perlでディレクトリ名だけを取得したいのですが、
なかなかうまい方法が見つかりません。
ファイル名を取得する・・・というのは結構あるのですが、
ディレクトリ名だけ、というのがどうもわかりません。

ちなみにファイル名取得は以下のようにやっています。
my $md;
opendir(DIR, 'q');
while (defined($dir = readdir(DIR))) {
$md=substr($dir,0,6);
}
closedir(DIR);

ディレクトリ名だけを取得・・・というのはどうやればよいのでしょうか。

Aベストアンサー

ファイル名の取得で例示されているものは、ファイル名だけの取得できてませんよね?
質問者さんが書かれているスクリプトだと、
DIRの中にある「何か」の「たまたま」一番最後に入っていたものの「0文字目~6文字目」までを取得するスクリプトになっているのわかりますか?

my @file;
my @directory;
my $check_dir = "./q/";
$ct =0;
opendir(DIR,$check_dir);
while( defined($temp=readdir(DIR))){
#カレントディレクトリまたは上位ディレクトリの場合はパス
if( $temp eq '.' || $temp eq '..' ){ next;}
#ファイルの場合
if( -f $check_dir.$temp ){
push @file, $temp;
}
#ディレクトリの場合
if( -d $check_dir.$temp ){
push @directory, $temp;
}
}

$check_dirに設定されているディレクトリに格納されているファイルは@fileに、ディレクトリは@directoryに格納されます。

ファイル名の取得で例示されているものは、ファイル名だけの取得できてませんよね?
質問者さんが書かれているスクリプトだと、
DIRの中にある「何か」の「たまたま」一番最後に入っていたものの「0文字目~6文字目」までを取得するスクリプトになっているのわかりますか?

my @file;
my @directory;
my $check_dir = "./q/";
$ct =0;
opendir(DIR,$check_dir);
while( defined($temp=readdir(DIR))){
#カレントディレクトリまたは上位ディレクトリの場合はパス
if( $temp eq '.' || $temp eq '..' ){...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング