Unixで2つのCSVファイル間のヘッダを確認するには?

Unixで2つのCSVファイル間のヘッダを確認するには?
File1 - filename.csv
File2 - filename.csv

kshスクリプトを使用して、Linux上でこれら2つのファイル間のヘッダーを比較したいと思います。

ケース 1:-

たとえば、file1のヘッダーはINPUT -->です。

NAME,UNIT CODE, VAR
JAMES01,IPU UNIT,OTHER
FIERCY,AUTOIMMUNE,OTHER

file2 のヘッダーは INPUT です。 -->

出力:- これら2つのファイル間のヘッダーの一致

ケース 2:-

file1のヘッダーがINPUT --> plant、動物、オブジェクト、file2のヘッダーがINPUT --> plant、動物、オブジェクト、ツリーであるとします。

出力 - 追加の列があります。 EXCESS COLUMN NAME IS 'tree'

注 - ヘッダーはハードコードされず、csvファイルから取得されます。とても感謝しています!

答え1

最も簡単な方法は、各ファイルの最初の行を比較し、同じかどうかに応じて正しいディレクトリに移動することです。

$ diff -qs <(head -n1 file1.csv) <(head -n1 file2.csv) 
Files /dev/fd/63 and /dev/fd/62 differ

&&その後、(and)および||(or)演算子を使用して、結果に応じてファイルに対してさまざまな操作を実行できます。たとえば、file2.csv同じヘッダーがある場合は名前がディレクトリに移動しsame、異なる場合は名前がディレクトリに移動しますdifferent

$ mkdir -p same different
$ diff -qs <(head -n1 file1.csv) <(head -n1 file2.csv) && 
   mv file2.csv same/ || mv file2.cxv different/

どの特定のフィールドが異なるかを本当に知っておく必要があり、違いが常に最後のフィールドであることを確認できる場合は、次のようにします。

diff -qs <(head -n1 file1.csv) <(head -n1 file2.csv) >/dev/null && 
   echo "The headers are the same" ||
   echo "file2.csv has an extra entry: $(awk -F, '{ print $NF; exit}' file2.csv)"

処理が必要な場合どの違い、使用:

awk -F, 'BEGIN{ FS=OFS="," }
       { 
        if(NR==FNR){ 
          for(i=1; i<=NF; i++){ a[$i]++ }
        }
        else{ 
         for(i=1; i<=NF; i++){ 
          if (! ($i in a)){
            b[$i]++
          }
         }
        }
       }
       END{ 
            printf "The second file has extra fields: ";
            for( field in b){
                printf "\"%s\" ", field
           }
       }' file1.csv file2.csv

答え2

nextfileこれはおそらく、テストされていない状態でGNU awkなどのサポートされているawkを使用して実行したいことです。

awk '
    BEGIN { FS="," }
    FILENAME == ARGV[1] {
        nf = split($0,a)
        nextfile
    }
    FILENAME == ARGV[2] {
        nf = (NF > nf ? NF : nf)
        for ( i=1; i<=nf; i++ ) {
            if ( $i"" != a[i]"" ) {
                printf "Field %d difference: %s \"%s\" != %s \"%s\"\n", i, ARGV[1], a[i], FILENAME, $i
            }
        }
        exit
    }
' file1.csv file2.csv

あなたのawkがそれをサポートしていない場合は、nextfile以下を変更してください。

    FILENAME == ARGV[1] {
        nf = split($0,a)
        nextfile
    }

これに関して:

    FILENAME == ARGV[1] {
        if ( NR == 1 ) {
            nf = split($0,a)
        }
        next
    }

それでも動作しますが、最初の行だけでなく最初のファイル全体を読む必要があるため、遅く実行されます。

上記では、2番目のファイルが空ではないと仮定しています。可能であれば、FILENAME == ARGV[2]その位置から2番目の配列を埋め、ENDそのセクションで比較します。

関連情報