2017-04-14 6 views
1

私は、Linuxとperlプログラミングにはかなり新しいです。私は答えなしですべての検索オプションを使い果たしました。 私は、同じ行のアイテムが相互作用することがわかっている2つの列で知られているすべての相互作用を含むマスターファイル "master.txt"を持っています。私は、列1と列2に含まれている場合、マスターファイルから結果を返すための検索基準にしたい項目 "list.txt"のリストを持っています。すべてのファイルはタブで区切られています。例えばの場合: "master.txt"リストの部分文字列と別のファイルの複数の列を一致させよう

AppleP001 BallP002 
AppleP002 CatP001 
BallP001 DogP001 
BallP002 AppleP001 
CatP001 AppleP002 
DogP001 BallP001 
DogP002 ZebraP001 
ElephantP001 CardinalP001 
FishP001 AntelopeP001 

そして、この検索ファイル: "list.txtに"

Apple 
Ball 
Cat 
Dog 

結果のファイルは、Apple *、ボールだけ含まれている必要があり これはマスターファイルである場合両方の列に*、猫*と犬*が、重複した項目を削除します。

を私はgrepのを使用してみました:

grep -f list.txt master.txt > Sub_list.txt 

しかし、私はこの取得:

AppleP001  BallP002 
AppleP002  CatP001 
BallP001  DogP001 
BallP002  AppleP001 
CatP001 AppleP002 
DogP001 BallP001 
DogP002 ZebraP001 

どのように私は重複を削除(両方の項目が同じ行にある場合、それらが何であるかの列は関係ありません、それは重複を検討)し、出力ファイルから無関係なデータを削除するかをし、これを取れ?

AppleP001 BallP002 
AppleP002 CatP001 
BallP001 DogP001 

ご協力いただきありがとうございます。ありがとう。少し重い

+0

SOへようこそ。ここでの質問は、あなたのコードの詳細についてのものであることが期待されます(なぜ失敗したのか)。 [ヘルプページ](http://stackoverflow.com/help)を見てください。彼らは短く有益です。 – zdim

答えて

1

ファイルは非常に大きいですが、その問題はあなたが持つことができない場合は、出力が問題の説明

 
AppleP001 BallP002 
AppleP002 CatP001 
BallP001 DogP001 

の私の理解と一致する

use warnings; 
use strict; 
use feature 'say'; 
use Path::Tiny; 
use List::Util qw(uniq any all); 

my ($file, $flist) = ('master.txt', 'list.txt'); 

my @search = path($flist)->lines({ chomp => 1 }); 

# Sort words within each line so then filter out duplicate lines 
my @filtered = uniq map { join ' ', sort split } path($file)->lines; 

# Each word on the line needs to match a word in @search list 
my @result = grep { all { found($_, \@search) } split } @filtered; 

say for @result; 

sub found { return any { $_[0] =~ /^$_/ } @{$_[1]} } 

が言及されていない場合何らかの理由でpathを提供し、ファイルを開いてチェックし、path(...)->linesの代わりにファイルハンドルを読み込んで(リストコンテキストで)chomp @search;


ここでビット

# Each word on the line needs to match a word in @search list 
my @result = grep { 
    my ($w1, $w2) = split; 
    any { $w1 =~ /^$_/ } @search and any { $w2 =~ /^$_/ } @search; 
} @filtered; 
+0

ありがとうzdim!コメントは非常に役に立ち、コードを学ぶのに役立ちました。 –

0

を書き出さ最後の部分は、awkの1つである:

$ awk ' 
NR==FNR { a[$1]; next } # read list and hash to a 
{       # process master 
    b=""     # reset buffer 
    for(i in a)   # iterate thru a 
     if(index($0,i)) { # if list item is found in current master record 
      b=$0   # set the record to buffer 
      delete a[i] # remove list entry from a 
     } 
     if(b) print b  # print b 
}' list master    # mind the order 
AppleP001 BallP002 
AppleP002 CatP001 
BallP001 DogP001 
+0

Jamesありがとう!短いと甘いコードは、素晴らしい作品。 –

関連する問題