awkを使用した2つのファイルの比較

awkを使用した2つのファイルの比較

両方のファイルを比較し、特定のフィールドで一致する場合は出力を印刷しようとします。

ファイル1.txt:

bart:29482164591748
 apu:29482164591748
smithers:68468468468464
lisa:68468468468464
maggie:2348578903247548

ファイル2.txt:

68468468468464:keyboard
68463894578424:user
29482164591748:computer

私は次のような出力が欲しい。

bart:29482164591748:computer

答え1

古典作品join

join -t: -1 2 -2 1 -o 2.1,1.1,1.2 <(sort -t: -k1,1 file1) <(sort -t: -k2,2 file2)
  • -t:区切り文字でコロンを指定します。
  • -1 2file1の接続フィールドは2番目です。
  • -2 1file2の接続フィールドが最初です。
  • -o 2.1,1.1,1.2出力形式。
  • <(...)-k1,1:両方のファイルを結合フィールド(and)でソートし、-k2,2区切り-t:文字でコロンを指定する必要がありますsort

答え2

そしてawk

awk -F: 'NR==FNR{a[$1]=$2;next}a[$2]{print $1":"$2":"a[$2]}' file1 file2

出力:

bart:29482164591748:computer
smithers:68468468468464:keyboard
lisa:68468468468464:keyboard

説明する:

  • awk -F:フィールド区切り文字でコロンを処理するawkの開始
  • NR==FNR{}最初のファイルのみ処理
  • a[$1]=$2;next2番目のフィールドの値を使用して最初のフィールドにインデックス付きの配列を構築し、次の行に移動しますa
  • a[$2]{}2番目のフィールドの現在のインデックスを使用して、以前に生成された配列の値が空でない場合にのみ処理します(next前の式の単語のためにfile2に対してのみこれを実行します)。
  • print $1":"$2":"a[$2]必要に応じてすべてを印刷します。

質問が修正されました:

awk -F: 'NR==FNR{a[$1]=$2;next}a[$2]{print $1":"$2":"a[$2]}' file2 file1

出力:

bart:29482164591748:computer
 apu:29482164591748:computer
smithers:68468468468464:keyboard
lisa:68468468468464:keyboard

答え3

使用しませんawkが、使用しますperl

#!/usr/bin/env perl
use strict;
use warnings;

#open both files for reading
open( my $input1, '<', "file1.txt" ) or die $!;
open( my $input2, '<', "file2.txt" ) or die $!;

#read the key-values into a hash called lookup. 
my %lookup = do { local $/; <$input1> =~ m/(\d+):(\w+)/g; };

#iterate by line of second file
while ( <$input2> ) { 
    #trim trailing linefeeds
    chomp;
    #split current line on :
    my ( $user, $key ) = split /:/;
    #if exists in original lookup, display record 
    if ( $lookup{$key} ) {
        print join ( ":", $user, $key, $lookup{$key}),"\n";
    }
}

しかし、私が得た結果は少し異なります。具体的には次のようになります。

bart:29482164591748:computer
smithers:68468468468464:keyboard
lisa:68468468468464:keyboard

なぜ2番目ののかわからないしてはいけない一致するキー値に基づいて印刷します。

本質的に同じ単一の裏地が必要な場合:

perl -F: -lane "print $k{$F[0]}.':'.$_ if $k{$F[0]}; $k{$F[1]}//=$F[0];" file2.txt file1.txt

関連情報