keluaran awk ke file berdasarkan filter

Oct 21 2020

Saya memiliki CSVfile besar yang perlu saya potong menjadi beberapa bagian berdasarkan nilai di salah satu kolom. File masukan saya dataset.csvadalah seperti ini:

CATATAN : diedit untuk memperjelas bahwa data ,data,tidak ada spasi.

action,action_type, Result
up,1,stringA
down,1,strinB
left,2,stringC

Jadi, untuk membaginya, action_typesaya cukup melakukannya (saya membutuhkan seluruh baris yang cocok di file yang dihasilkan):

awk -F, '$2 ~ /^1$/ {print}' dataset.csv >> 1_dataset.csv
awk -F, '$2 ~ /^2$/ {print}' dataset.csv >> 2_dataset.csv

Ini berfungsi seperti yang diharapkan, tetapi pada dasarnya saya menelusuri kumpulan data asli saya dua kali. Dataset asli saya sekitar 5GB dan saya memiliki 30 action_typekategori. Saya perlu melakukan ini setiap hari, jadi, saya perlu membuat skrip untuk menjalankannya sendiri secara efisien.

Saya mencoba yang berikut ini tetapi tidak berhasil:

# This is a file called myFilter.awk

{
action_type=$2; if (action_type=="1") print $0 >> 1_dataset.csv;
else if (action_type=="2") print $0 >> 2_dataset.csv;
}

Lalu saya menjalankannya sebagai:

awk -f myFilter.awk dataset.csv

Tapi saya tidak mendapatkan apa-apa. Secara harfiah tidak ada, bahkan tidak ada kesalahan. Jenis mana yang memberi tahu saya bahwa kode saya tidak cocok dengan apa pun atau pernyataan cetak / pipa saya salah.

Jawaban

4 anubhava Oct 21 2020 at 04:16

Anda dapat mencoba awk ini untuk melakukan ini dalam satu perintah:

awk -F, 'NR > 1{fn = $2 "_dataset.csv"; print >> fn; close(fn)}' file
3 EdMorton Oct 21 2020 at 05:12

Dengan GNU awk untuk menangani banyak file yang terbuka secara bersamaan dan tanpa mereplikasi baris header di setiap file output:

awk -F',' '{print > ($2 "_dataset.csv")}' dataset.csv

atau jika Anda juga ingin agar baris header muncul di setiap file output, maka dengan GNU awk:

awk -F',' '
    NR==1 { hdr = $0; next }
    !seen[$2]++ { print hdr > ($2 "_dataset.csv") }
    { print > ($2 "_dataset.csv") }
' dataset.csv

atau sama dengan awk:

awk -F',' '
    NR==1 { hdr = $0; next }
    { out = $2 "_dataset.csv" } !seen[$2]++ { print hdr > out }
    { print >> out; close(out) }
' dataset.csv
1 markp-fuso Oct 21 2020 at 04:23

Seperti yang saat ini dikodekan, pemisah bidang masukan belum ditentukan.

Arus:

$ cat myfilter.awk { action_type=$2;
if (action_type=="1") print $0 >> 1_dataset.csv; else if (action_type=="2") print $0 >> 2_dataset.csv;
}

Doa:

$ awk -f myfilter.awk dataset.csv

Ada beberapa cara untuk mengatasinya:

$ awk -v FS="," -f myfilter.awk dataset.csv

atau

$ cat myfilter.awk BEGIN {FS=","} { action_type=$2
if (action_type=="1") print $0 >> 1_dataset.csv; else if (action_type=="2") print $0 >> 2_dataset.csv;
}

$ awk -f myfilter.awk dataset.csv