Ekstrak data dari file dan tempatkan di file yang berbeda berdasarkan nilai satu kolom

14

Kami akan menghasilkan file csv dengan nilai di bawah ini

yp1234,577,1,3
yp5678,577,3,5
yp9012,132,8,9

Saya perlu mengekstrak data dan membuat file berdasarkan kolom kedua. Jika 577 maka seluruh baris harus diekstraksi dan ditempatkan dalam file terpisah. Maksud saya, saya memerlukan file yang memiliki baris dengan kolom kedua sebagai 577 saja dan file lain dengan kolom kedua sebagai 132 saja

Saya mencoba menggunakan IF tetapi tidak berhasil

pengguna3116123
sumber
5
Sebenarnya memposting kode yang tidak berfungsi selalu merupakan ide yang bagus.
goldilocks

Jawaban:

27

Gunakan awk:

awk -F, '{ print > $2 ".csv" }' file.csv

Ini akan membuat dua file 577.csvdan 132.csvdalam direktori Anda saat ini.

Perintah di atas mengasumsikan bahwa Anda hanya dapat memiliki 132atau 577sebagai bidang kedua. Ini akan membuat satu nama file untuk masing-masing nilai yang ditemukan di bidang kedua dari keseluruhan file.csv.

Jika ada nilai lain selain dari dua yang Anda minati, dan Anda ingin mengabaikan garis itu, lakukan ini sebagai gantinya:

awk -F, '$2 == "577" || $2 == "132" { print > $2 ".csv" }' file.csv
terdon
sumber
1
Ada awkimplementasi buggy yang tidak bisa digunakan print > $2 ".cvs". Pada orang-orang, Anda harus menghitung pertama nama file, kemudian lakukan print: fname = $2 ".cvs"; print > fname.
Kusalananda
3

Saya suka awksolusi terdon , tetapi demi kelengkapan, berikut ini saran hanya menggunakanbash

while IFS=, read -r a1 a2 a3 a4; do 
    echo "$a1,$a2,$a3,$a4" >> "$a2".csv
done < file.csv

Ini akan menghasilkan file 577.csvdan 132.csvdalam direktori saat ini.

grebneke
sumber
3

Untuk mengekstrak semua 577 ke stdout

grep -e '^.*,577,.*,.*$' youfile.csv >result_extract_557.csv

- sunting 1 Dikoreksi, berdasarkan komentar @ terdon di bawah untuk menghindari kecocokan salah ketika setidaknya 3 koma sesuai dengan 577.

grep -e '^[:alnum:]*,577,[:digit:]*,[:digit:]*$' youfile.csv >result_extract_557.csv

Tapi saya pikir awksolusinya lebih komprehensif.

X Tian
sumber
Itu akan cocok bahkan jika 577 ada di bidang lain, bukan yang kedua atau jika itu adalah bagian dari bidang. Misalnya foo577baratau yp9012,132,8,577.
terdon
Saya pikir koma saya akan membuatnya tergantung pada posisi lapangan?
X Tian
Maaf, saya memberikan contoh yang buruk tetapi .*juga dapat mencocokkan koma sehingga Anda tidak tahu bidang mana yang cocok. Bisa jadi yang kedua, bisa juga yang ke-45. Keluhan kedua saya salah, Anda benar bahwa koma melindungi dari pencocokan foo577bar.
terdon
apa yang harus dilakukan jika | karakter digunakan sebagai ganti,.
user3116123
menerima kesalahan grep di bawah ini: opsi ilegal - e Penggunaan: grep -hblcnsviw file pola. . .
user3116123
1

Menggunakan csvkit:

$ csvgrep -c 2 -m 577 data.csv >output.csv

The -c 2merek cvsgrepmenganggap kolom kedua, dan dengan -m 577kita meminta untuk mencocokkan string 577di kolom tersebut.

Berikut ini akan ditulis untuk output.csv:

yp1234,577,1,3
yp5678,577,3,5

Untuk mencocokkan sejumlah string dan menulis output ke file untuk setiap string:

for pattern in 577 132; do
  csvgrep -c 2 -m "$pattern" data.csv >"output-$pattern.csv"
done

Ini akan membuat dua file output-132.csvdan output-577.csv.

Kusalananda
sumber