次の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
:head
tail
sort
ファイル名を配列として保存してから
- 最初のファイルのヘッダー行を印刷します。
- 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ファイルにあります。