2

4つのファイルがあり、他のファイルの要素と比較して(ファイルごとに)重複していない要素を知りたいです。

ファイルA

Vincy
ruby
rome

ファイルB

Vincy
rome
Peter

ファイルC

Vincy
Paul
alex

ファイルD

Vincy
rocky
Willy

perl、python、shell、bashの1つのライナーに関する提案。期待される出力は次のとおりです。

ファイルA ruby:、ファイルB Peter:、ファイルC :、ファイルD:Paul、。AlexrockyWilly

4

4 に答える 4

10

質問が明確になった後に編集する:すべてのファイルにまたがる固有の要素、およびそれが発生するファイル:

cat File_A File_B File_C File_D |sort | uniq -u | while read line ; do file=`grep -l $line File*` ; echo "$file $line" ; done

編集:

それを行うための適切な方法は、ファイルが大きい場合はより速くなります:

#!/usr/bin/perl

use strict;
use autodie;

my $wordHash ;

foreach my $arg(@ARGV){
    open(my $fh, "<", $arg);
    while(<$fh>){
        chomp;
        $wordHash->{$_}->[0] ++;
        push(@{$wordHash->{$_}->[1]}, $arg);
    }
}

for my $word ( keys %$wordHash ){
    if($wordHash->{$word}->[0] eq 1){
        print $wordHash->{$_}->[1]->[0] . ": $word\n"
    }
}

次のように実行します:myscript.pl filea fileb filec ... filezz

明確化前のもの: シェルコマンドで十分簡単。すべてのファイルで繰り返されない要素

cat File_A File_B File_C File_D |sort | uniq -u

すべてのファイルにまたがる固有の要素

cat File_A File_B File_C File_D |sort | uniq

ファイルごとの一意の要素(@Dennis Williamsonに感謝します)

for line in File* ; do echo "working on $line" ; sort $line | uniq ; done
于 2012-06-21T15:00:28.523 に答える
4

これは、任意の数のファイルに対して要求したことを実行する簡単なPythonスクリプトです。

from sys import argv
from collections import defaultdict

filenames = argv[1:]
X = defaultdict(list)
for f in filenames:
    with open(f,'r') as FIN:
        for word in FIN:
            X[word.strip()].append(f)

for word in X:
    if len(X[word])==1:
        print "Filename: %s word: %s" % (X[word][0], word)

これは与える:

Filename: D word: Willy
Filename: C word: alex
Filename: D word: rocky
Filename: C word: Paul
Filename: B word: Peter
Filename: A word: ruby
于 2012-06-21T15:14:48.807 に答える
1

ホットニードル:

import sys
inputs = {}
for inputFileName in sys.args[1:]:
  with open(inputFileName, 'r') as inputFile:
    inputs[inputFileName] = set([ line.strip() for line in inputFile ])
for inputFileName, inputSet in inputs.iteritems():
  print inputFileName
  result = inputSet
  for otherInputFileName, otherInputSet in inputs.iteritems():
    if otherInputFileName != inputFileName:
      result -= otherInputSet
  print result

でもやってみませんでした;-)

于 2012-06-21T15:16:20.460 に答える
1

Perlワンライナー、コメント付きの読みやすいバージョン:

perl -nlwe '     
    $a{$_}++;     # count identical lines with hash
    push @a, $_;  # save lines in array
    if (eof) { push @b,[$ARGV,@a]; @a=(); }   # at eof save file name and lines
    }{ # eskimo operator, executes rest of code at end of input files
    for (@b) { 
        print shift @$_;                      # print file name
        for (@$_) { print if $a{$_} == 1 };   # print unique lines
    }
' file{A,B,C,D}.txt

注:eofは、個々の入力ファイルごとです。

バージョンのコピー/貼り付け:

perl -nlwe '$a{$_}++; push @a, $_; if (eof) { push @b,[$ARGV,@a]; @a=(); } }{ for (@b) { print shift @$_; for (@$_) { print if $a{$_} == 1 } }' file{A,B,C,D}.txt

出力:

filea.txt
ruby
fileb.txt
Peter
filec.txt
Paul
alex
filed.txt
rocky
Willy

注:これは予想よりも難しい作業でした。もっときれいにする方法があると思いますが、今はこれを投稿して、クリーンアップできるかどうかを確認します。

于 2012-06-21T15:33:44.540 に答える