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
そのセクションで比較します。