さまざまなファイルをマージ/ソートし、ヘッダーを一番上に保つ

さまざまなファイルをマージ/ソートし、ヘッダーを一番上に保つ

次の3つのファイルセットがあります。

cat "110001_test file_first_file.csv"
ID,NAME,LOCATION
1,Vikrant,Gurgaon
2,Bharat,Noida
3,Raju,Hyderabad

cat "110001_test file_second_file.csv"
ID,NAME,LOCATION
1,Vikrant,Gurgaon
22,abcd,Noida
3,Raju,Hyderabad

cat "110001_test file_third_file.csv"
ID,NAME,LOCATION
1,Vikrant,Gurgaon
2,Bharat,Noida
33,xyz,Hyderabad

以下のコマンドを使用してこれらのファイルをマージし、ヘッダーを一番上に保持し、重複したエントリがある場合は削除しました。

find . -type f -name '*test file*.csv' -exec cat {} + | awk 'NR == 1; NR > 1 {print $0 | "sort -u"}' > output.file

私に提供される結果は次のとおりです。

ID,NAME,LOCATION
1,Vikrant,Gurgaon
22,abcd,Noida
2,Bharat,Noida
33,xyz,Hyderabad
3,Raju,Hyderabad
ID,NAME,LOCATION

私はここで何が起こっていて、コマンドが何をしているのか理解しています。デフォルトでは、最初の行を無視して別のレコードを選択して、その中の重複する項目を並べ替えて削除します。したがって、出力ファイルの下部に追加のヘッダーが表示されます。

このような出力を期待しています。

ID,NAME,LOCATION
1,Vikrant,Gurgaon
22,abcd,Noida
2,Bharat,Noida
33,xyz,Hyderabad
3,Raju,Hyderabad

答え1

使用とbash:headtailsort

ファイル名を配列として保存してから

  • 最初のファイルのヘッダー行を印刷します。
  • 2行目から、すべてのファイルの内容とsort固有のオプションを使用して結果を出力します。
  • 出力をファイルにリダイレクトする
files=( *test*.csv )
{
  head -n1 "${files[0]}"
  for i in "${files[@]}"; do
    tail -n+2 "$i"
  done | sort -u
} > output

答え2

NR>1すべてのファイルを最初に使用してリンクすることに頼ることはできません。cat {} +
このようにできるだけコードを再利用しようとしています。

{ 
    awk 'NR==1{print;exit}' *test*file*csv
    find . -type f -name '*test*file.csv' -exec awk 'NR>1' {} \; |
    sort -u
} > output.file

結果ファイル

ID,NAME,LOCATION
1,Vikrant,Gurgaon
22,abcd,Noida
2,Bharat,Noida
33,xyz,Hyderabad
3,Raju,Hyderabad

検索 -exec{}+

-execコマンド{} +
-exec操作のこのバリエーションは、選択したファイルに対して指定されたコマンドを実行しますが、コマンドラインは選択した各ファイル名を最後に追加することによって構成されます。

だから直列に接続しました。

答え3

以下を実行してください。

find . -type f -name '*test*file.csv' -exec awk '!seen[$0]++' {} +

awkが読み取る各行について、以前に(!)という連想配列に設定されていない場合ボン配列に追加され、条件が「true」と確認されるため、対応する行が出力されます。 awkが同じ行を読み取ると、条件が「false」になり、重複をスキップします。

awk では$0行全体を意味します。ここでは、これを配列キーとして使用し、すべてのキー(行)を読み取るたびに値が増加します。行の場合、配列に設定されていない場合、値は0で印刷され、キー値が0より大きい場合はスキップされます。

答え4

コマンドラインを少し変更すると、目的の結果が得られます。

awk 'NR<2||FNR>1' ./*test_file*.csv > temp ;
( head -n 1; sort -u; ) < temp > output.file

結果はoutput.fileファイルにあります。

関連情報