2つのファイルの内容を比較するAWKスクリプト

2つのファイルの内容を比較するAWKスクリプト

ファイルが2つあります。

ファイル1:

abc|123|check
def|456|map
ijk|789|globe
lmn|101112|equator

ファイル2:

check
map
equator
globe 

AWK関数は、file1の3番目の列(3番目の列を切り捨ててソートした後)をfile2のソートされた内容と比較する必要があります。

  • すべての行が一致した場合は1を返す必要があります。
  • それ以外の場合は2を返す必要があります。

答え1

function are_all_there {
    local num_diff=$(comm -3 <(cut -d'|' -f3 "$1" | sort) <(sort "$2") | wc -l)
    (( num_diff == 0 )) && return 1 || return 2
}

答え2

awkあなたの意見によると、これは唯一の選択ではないようです。したがって、これはawkではない方法です。
あなたは必要性に言及していませんユニーク質問では比較しましたが、uniqコメントの例では使用しました。必要でない場合ユニーク一致する場合は、ソートオプションを削除します-u。 (でテスト済みbash)。

(($(comm -3 <( cut -d'|' -f3 file1 | sort -u ) \
            <( sort -u file2 ) | wc -l))) && echo 2 - not all match ||
                                             echo 1 - all match

またはawk-in を使用して最終比較を実行しますpaste

paste <( cut -d'|' -f3 file1 | sort -u ) \
      <( sort -u file2 ) |
   awk '$1!=$2{m=2; exit} 
     END{ if(m == 2){print "2 - not all match"; exit;} 
                     print "1 - all match";}' 

または、awk 2つの入力ファイルの比較

 awk '{if(NR == FNR){a[NR]=$1}
       else{ if($1 != a[NR]){m=2; exit}}}  
      END{ if(m == 2){print "2 - not all match"; exit;} 
                      print "1 - all match";}' \
    <( cut -d'|' -f3 file1 | sort -u ) \
    <( sort -u file2 ) |

答え3

興味深いCSの答え!これは純粋なセット比較なので、実際には何も並べ替える必要はありません。

入力ファイルは、要素がペアで構成されるセットを表します。たとえば、で行がfoo3回表示された場合は、file1<、3>要素を意味しますfoo。 3回file2含まれると、両方のセットがfooその要素を含むことを意味します。繰り返し回数が異なるか含まれていfile2ない場合は、セットに<、3>が含まれていないことを意味します。foofoofoo

また、<、3>などのペアセットは、キーを3にfooマップするハッシュとして表示できます。foo

TXR Lisp awkマクロ:

(awk (:begin (set fs "|"))
     (:let (h1 (hash :equal-based)) (h2 (hash :equal-based)))
     ((= arg 1) (inc [h1 [f 2] 0]))
     ((= arg 2) (inc [h2 rec 0]))
     (:end (exit (equal h1 h2))))

ファイルが所望の方法で同じであれば、成功した終了状態が生成され、そうでなければ失敗状態が生成される。

$txr comp.tl ファイル1 ファイル2
$エコ$?
0
$エコーマッピング>>ファイル2
$txr comp.tl ファイル1 ファイル2
$エコ$?
1

「1」または「2」の出力を解析して呼び出し元を複雑にするには、ルールを変更するだけです:end

(:end (prn (if (equal h1 h2) "1" "2")))

これは通常のawkの場合です。主な違いは、簡潔な構文があり、参照する変数を定義する必要がないことです。一方、2つの連想配列を比較して追跡する独自のarg変数を生成するには、一対のループを作成する必要があります。私たちが作業しているファイルのうち(GNU AwkはARGINDこの目的に役立ちます。)

BEGIN { FS = "|" }
FNR == 1 { arg++ }
arg == 1 { h1[$3]++; }
arg == 2 { h2[$0]++; }
END { same = 1
      for (i in h1)
        if (h1[i] != h2[i]) {
          same = 0
          break
        }
      if (same)
        for (i in h2)
          if (h2[i] != h1[i]) {
            same = 0
            break
          }
      print same ? "1" : "2"; }

関連情報