Bash'de CSV Verileri Nasıl Ayrıştırılır

Yayınlanan: 2022-09-16
Jane Kelly/Shutterstock.com

Virgülle Ayrılmış Değerler (CSV) dosyaları, dışa aktarılan veriler için en yaygın biçimlerden biridir. Linux'ta Bash komutlarını kullanarak CSV dosyalarını okuyabiliriz. Ama çok hızlı, çok karmaşık hale gelebilir. Bir el uzatacağız.

CSV Dosyası Nedir?

Virgülle Ayrılmış Değerler dosyası, tablolaştırılmış verileri tutan bir metin dosyasıdır. CSV, bir tür sınırlandırılmış veridir. Adından da anlaşılacağı gibi , her bir veri veya değer alanını komşularından ayırmak için virgül “ ” kullanılır.

CSV Dosyası Nedir ve Nasıl Açılır?
İLGİLİ CSV Dosyası Nedir ve Nasıl Açılır?

CSV her yerdedir. Bir uygulamanın içe ve dışa aktarma işlevleri varsa, neredeyse her zaman CSV'yi destekler. CSV dosyaları insan tarafından okunabilir. Daha azıyla içlerine bakabilir, herhangi bir metin düzenleyicide açabilir ve programdan programa taşıyabilirsiniz. Örneğin, verileri bir SQLite veritabanından dışa aktarabilir ve LibreOffice Calc'de açabilirsiniz.

Ancak, CSV bile karmaşık hale gelebilir. Veri alanında virgül olmasını ister misiniz? Bu alanın etrafına tırnak işareti “ " ” sarılmış olmalıdır. Bir alana tırnak işareti eklemek için her bir tırnak işaretinin iki kez girilmesi gerekir.

Elbette, yazdığınız bir program veya komut dosyası tarafından oluşturulan CSV ile çalışıyorsanız, CSV formatı muhtemelen basit ve anlaşılır olacaktır. Linux'un Linux olduğu daha karmaşık CSV formatlarıyla çalışmak zorunda kalırsanız, bunun için de kullanabileceğimiz çözümler var.

Bazı Örnek Veriler

Online Data Generator gibi siteleri kullanarak bazı örnek CSV verilerini kolayca oluşturabilirsiniz. İstediğiniz alanları tanımlayabilir ve kaç satır veri istediğinizi seçebilirsiniz. Verileriniz gerçekçi kukla değerler kullanılarak oluşturulur ve bilgisayarınıza indirilir.

50 satırlık sahte çalışan bilgilerini içeren bir dosya oluşturduk:

  • id : Basit bir benzersiz tamsayı değeri.
  • firstname : Kişinin adı.
  • soyadı : Kişinin soyadı.
  • job-unvan : Kişinin iş unvanı.
  • email-address : Kişinin e-posta adresi.
  • şube : Çalıştıkları şirket şubesi.
  • state : Şubenin bulunduğu eyalet.

Bazı CSV dosyalarının alan adlarını listeleyen bir başlık satırı vardır. Örnek dosyamızda bir tane var. İşte dosyamızın başı:

Örnek CSV dosyası

İlk satır, alan adlarını virgülle ayrılmış değerler olarak tutar.

CSV dosyasından Verileri Ayrıştırma

CSV dosyasını okuyacak ve her kayıttan alanları çıkaracak bir script yazalım. Bu komut dosyasını bir düzenleyiciye kopyalayın ve “field.sh” adlı bir dosyaya kaydedin.

 #! /bin/bash

while IFS="," read -r id ad soyadı iş unvanı e-posta şube durumu
yapmak
  echo "Kayıt Kimliği: $id"
  echo "Ad: $ad"
  echo "Soyadı: $soyad"
  echo "İş Unvanı: $jobtitle"
  echo "E-posta ekleme: $email"
  echo " Şube: $dal"
  echo "Durum: $durum"
  Eko ""
yapıldı < <(kuyruk -n +2 örnek.csv)

Küçük senaryomuzda oldukça fazla şey var. Hadi parçalayalım.

Linux Bash Komut Dosyasında Satır Satır Dosya Nasıl İşlenir
İLGİLİ Linux Bash Komut Dosyasında Bir Dosyayı Satır Satır Nasıl İşlenir

Bir while döngüsü kullanıyoruz. while döngüsü koşulu doğru olduğu sürece, while döngüsünün gövdesi yürütülür. Döngünün gövdesi oldukça basittir. Bazı değişkenlerin değerlerini terminal penceresine yazdırmak için bir echo ifadesi koleksiyonu kullanılır.

while döngüsü koşulu, döngünün gövdesinden daha ilginçtir. IFS="," deyimi ile dahili alan ayırıcı olarak virgül kullanılması gerektiğini belirtiyoruz. IFS bir ortam değişkenidir. read komutu, metin dizilerini ayrıştırırken değerine başvurur.

Verilerde olabilecek ters eğik çizgileri yok saymak için read komutunun -r (ters eğik çizgileri koru) seçeneğini kullanıyoruz. Normal karakterler olarak kabul edilecekler.

read komutunun ayrıştırdığı metin, CSV alanlarından sonra adlandırılan bir dizi değişkende depolanır. Aynı şekilde field1, field2, ... field7 olarak adlandırılabilirlerdi, ancak anlamlı isimler hayatı kolaylaştırır.

Veriler tail komutundan çıktı olarak elde edilir. tail kullanıyoruz çünkü bize CSV dosyasının başlık satırını atlamanın basit bir yolunu sunuyor. -n +2 (satır numarası) seçeneği, tail iki numaralı satırdan okumaya başlamasını söyler.

<(...) yapısına süreç ikamesi denir. Bash'in bir sürecin çıktısını bir dosya tanıtıcısından geliyormuş gibi kabul etmesine neden olur. Bu daha sonra while döngüsüne yönlendirilir ve read komutunun ayrıştıracağı metin sağlanır.

Komut dosyasını chmod komutunu kullanarak yürütülebilir hale getirin. Bu makaleden her komut dosyası kopyaladığınızda bunu yapmanız gerekecektir. Her durumda uygun komut dosyasının adını değiştirin.

 chmod +x alan.sh 

chmod ile çalıştırılabilir bir komut dosyası yapma

Komut dosyasını çalıştırdığımızda, kayıtlar, her bir alan farklı bir değişkende depolanacak şekilde, kendi kurucu alanlarına doğru bir şekilde bölünür.

 ./field.sh 

field.sh komut dosyası tarafından ayrıştırılan CSV dosyası.

Her kayıt bir dizi alan olarak yazdırılır.

Alanları Seçme

Belki de her alanı almak istemiyoruz veya buna ihtiyacımız yok. cut komutunu dahil ederek bir alan seçimi elde edebiliriz.

Bu komut dosyası "select.sh" olarak adlandırılır.

 #!/bin/bash

while IFS="," read -r id jobtitle şube durumu
yapmak
  echo "Kayıt Kimliği: $id"
  echo "İş Unvanı: $jobtitle"
  echo " Şube: $dal"
  echo "Durum: $durum"
  Eko ""
yapıldı <(cut -d "," -f1,4,6,7 sample.csv | tail -n +2)

İşlem ikame maddesine cut komutunu ekledik. -d (sınırlayıcı) seçeneğini, cut sınırlayıcı , “ ” kullanmasını söylemek için kullanıyoruz. -f (alan) seçeneği, cut bir, dört, altı ve yedi numaralı alanları istediğimizi söyler. Bu dört alan, while döngüsünün gövdesinde yazdırılan dört değişkene okunur.

Komut dosyasını çalıştırdığımızda elde ettiğimiz şey budur.

 ./select.sh 

Belirli bir alan seçimini çıkarmak için CSV dosyasını field.sh ile ayrıştırma

cut komutunu ekleyerek istediğimiz alanları seçip, istemediklerimizi yok sayabiliyoruz.

Şimdiye kadar, çok iyi. Fakat…

Uğraştığınız CSV, alan verilerinde virgül veya tırnak işareti olmadan karmaşık değilse, ele aldıklarımız muhtemelen CSV ayrıştırma ihtiyaçlarınızı karşılayacaktır. Karşılaşabileceğimiz sorunları göstermek için, küçük bir veri örneğini şöyle görünecek şekilde değiştirdik.

 id,ad,soyadı,iş unvanı,e-posta adresi,şube,devlet
1,Rosalyn,Brennan,"Steward, Senior",[email protected],Minneapolis,Maryland
2,Danny,Redden,"Analyst ""Budget""",[email protected],Venedik,Kuzey Karolina
3,Lexi,Roscoe,Eczacı,,Irlington,Vermont
  • Birinci kaydın job-title alanında virgül vardır, bu nedenle alanın tırnak içine alınması gerekir.
  • İkinci kayıt, jobs-title alanında iki çift tırnak içine alınmış bir kelimeye sahiptir.
  • Üçüncü kayıtta email-address alanında veri yok.

Bu veriler “sample2.csv” olarak kaydedildi. “field.sh” komut dosyanızı “sample2.csv” olarak adlandıracak şekilde değiştirin ve “field2.sh” olarak kaydedin.

 #! /bin/bash

while IFS="," read -r id ad soyadı iş unvanı e-posta şube durumu
yapmak
  echo "Kayıt Kimliği: $id"
  echo "Ad: $ad"
  echo "Soyadı: $soyad"
  echo "İş Unvanı: $jobtitle"
  echo "E-posta ekleme: $email"
  echo " Şube: $dal"
  echo "Durum: $durum"
  Eko ""
yapıldı < <(kuyruk -n +2 sample2.csv)

Bu betiği çalıştırdığımızda, basit CSV ayrıştırıcılarımızda görünen çatlakları görebiliriz.

 ./alan2.sh 

field2.sh'yi çalıştırma

İlk kayıt, iş unvanı alanını iki alana böler ve ikinci kısmı e-posta adresi olarak değerlendirir. Bundan sonraki her alan bir yer sağa kaydırılır. Son alan hem branch hem de state değerlerini içerir.

Alanı iki alana bölünmüş bir kayıt

İkinci kayıt tüm tırnak işaretlerini korur. "Bütçe" kelimesinin etrafında yalnızca bir çift tırnak işareti olmalıdır.

Yanlış kullanılan tırnak işaretleri içeren bir kayıt

Üçüncü kayıt aslında eksik alanı gerektiği gibi işler. E-posta adresi eksik, ancak her şey olması gerektiği gibi.

Doğru şekilde işlenen, alanı eksik olan bir kayıt

Sezgisel olarak, basit bir veri formatı için sağlam bir genel durum CSV ayrıştırıcısı yazmak çok zordur. awk gibi araçlar yaklaşmanıza izin verir, ancak her zaman gözden kaçan uç durumlar ve istisnalar vardır.

awk Komutu Linux'ta Nasıl Kullanılır
İLGİLİ Linux'ta awk Komutu Nasıl Kullanılır

Hatasız bir CSV ayrıştırıcısı yazmaya çalışmak muhtemelen ileriye dönük en iyi yol değildir. Alternatif bir yaklaşım - özellikle bir tür son teslim tarihine kadar çalışıyorsanız - iki farklı strateji kullanır.

Biri, verilerinizi işlemek ve çıkarmak için amaca yönelik tasarlanmış bir araç kullanmaktır. İkincisi, verilerinizi sterilize etmek ve katıştırılmış virgül ve tırnak işaretleri gibi sorun senaryolarını değiştirmektir. Basit Bash ayrıştırıcılarınız daha sonra Bash dostu CSV ile başa çıkabilir.

csvkit Araç Takımı

CSV araç seti csvkit , CSV dosyalarıyla çalışmaya yardımcı olmak için açıkça oluşturulmuş bir yardımcı programlar topluluğudur. Bilgisayarınıza yüklemeniz gerekecek.

Ubuntu'ya kurmak için şu komutu kullanın:

 sudo apt yükleme csvkit 

Ubuntu'da csvkit kurulumu

Fedora'ya yüklemek için şunu yazmanız gerekir:

 sudo dnf python3-csvkit'i kurun 

Fedora'ya csvkit yükleme

Manjaro'da komut şudur:

 sudo pacman -S csvkit 

Manjaro'ya csvkit yükleme

Bir CSV dosyasının adını ona iletirsek, csvlook yardımcı programı her alanın içeriğini gösteren bir tablo görüntüler. Alan içeriği, CSV dosyasında depolandıkları gibi değil, alan içeriklerinin neyi temsil ettiğini göstermek için görüntülenir.

Sorunlu “sample2.csv” dosyamızla csvlook deneyelim.

 csvlook örnek2.csv 

zahmetli CSV, csvlook tarafından doğru şekilde ayrıştırıldı

Tüm alanlar doğru şekilde görüntüleniyor. Bu, sorunun CSV olmadığını kanıtlar. Sorun şu ki, betiklerimiz CSV'yi doğru şekilde yorumlamak için çok basit.

Belirli sütunları seçmek için csvcut komutunu kullanın. -c (sütun) seçeneği, alan adları veya sütun numaraları veya her ikisinin karışımı ile kullanılabilir.

Her kayıttan ad ve soyadları, iş unvanları ve e-posta adreslerini çıkarmamız gerektiğini varsayalım, ancak ad sırasını “soyadı, ad” olarak almak istiyoruz. Tek yapmamız gereken alan adlarını veya numaralarını istediğimiz sıraya koymak.

Bu üç komutun hepsi eşdeğerdir.

 csvcut -c soyadı,ad,iş unvanı,e-posta adresi sample2.csv
 csvcut -c soyadı,ad,4,5 sample2.csv
 csvcut -c 3,2,4,5 örnek2.csv 

csvcut ile alanları tercih edilen sırayla seçme

Çıktıyı bir alana göre sıralamak için csvsort komutunu ekleyebiliriz. Sıralanacak sütunu belirtmek için -c (sütun) seçeneğini ve azalan düzende sıralamak için -r (ters) seçeneğini kullanıyoruz.

 csvcut -c 3,2,4,5 örnek2.csv | csvsort -c 1 -r 

Alanları seçme ve bunları tek bir sütuna göre sıralama

Çıktıyı daha güzel hale getirmek için csvlook aracılığıyla besleyebiliriz.

 csvcut -c 3,2,4,5 örnek2.csv | csvsort -c 1 -r | csvlook 

Sıralanmış alan seçimini güzel bir şekilde yazdırmak için csvlook kullanma

Düzgün bir dokunuş, kayıtlar sıralansa bile, alan adlarının bulunduğu başlık satırının ilk satır olarak tutulmasıdır. Verileri istediğimiz şekilde elde ettiğimiz için mutlu olduğumuzda, csvlook komut zincirinden kaldırabilir ve çıktıyı bir dosyaya yeniden yönlendirerek yeni bir CSV dosyası oluşturabiliriz.

“sample2.file” dosyasına daha fazla veri ekledik, csvsort komutunu kaldırdık ve “sample3.csv” adında yeni bir dosya oluşturduk.

 csvcut -c 3,2,4,5 numune2.csv > numune3.csv 

CSV Verilerini Temizlemenin Güvenli Yolu

LibreOffice Calc'de bir CSV dosyası açarsanız, her alan bir hücreye yerleştirilecektir. Virgül aramak için bul ve değiştir işlevini kullanabilirsiniz. Bunları ortadan kaybolmaları için “hiçbir şey” ile veya noktalı virgül gibi CSV ayrıştırmasını etkilemeyecek bir karakterle değiştirebilirsiniz “ ; " örneğin.

Alıntılanan alanların çevresinde tırnak işaretleri görmezsiniz. Göreceğiniz tek tırnak işaretleri, alan verilerinin içindeki gömülü tırnak işaretleridir. Bunlar tek tırnak içinde gösterilir. Bunları bulmak ve tek bir kesme işareti “ ' ” ile değiştirmek, CSV dosyasındaki çift tırnak işaretinin yerini alacaktır.

Tırnak işaretlerini kesme işaretiyle değiştirmek için LibreOffice Calc'ın bul ve değiştir özelliğini kullanma

Bul ve değiştir LibreOffice Calc gibi bir uygulamada yapmak, alan ayırıcı virgüllerin hiçbirini yanlışlıkla silemeyeceğiniz veya alıntı yapılan alanların etrafındaki tırnak işaretlerini silemeyeceğiniz anlamına gelir. Yalnızca alanların veri değerlerini değiştireceksiniz.

Noktalı virgüllü alanlardaki tüm virgülleri ve kesme işaretli tüm gömülü tırnak işaretlerini değiştirdik ve değişikliklerimizi kaydettik.

Değiştirilen CSV dosyası

Ardından, “sample3.csv”yi ayrıştırmak için “field3.sh” adlı bir komut dosyası oluşturduk.

 #! /bin/bash

while IFS="," read -r soyadı ad iş unvanı e-postası
yapmak
  echo "Soyadı: $soyad"
  echo "Ad: $ad"
  echo "İş Unvanı: $jobtitle"
  echo "E-posta ekleme: $email"
  Eko ""
yapıldı < <(kuyruk -n +2 sample3.csv)

Bakalım çalıştırdığımızda ne elde edeceğiz.

 ./field3.sh 

Doğru şekilde ayrıştırılmış CSV'nin bir bölümü

Basit ayrıştırıcımız artık daha önce sorunlu kayıtlarımızı işleyebilir.

Çok Fazla CSV Göreceksiniz

CSV, muhtemelen uygulama verileri için ortak bir dile en yakın şeydir. Bir tür veriyi işleyen çoğu uygulama, CSV'yi içe ve dışa aktarmayı destekler. CSV'yi gerçekçi ve pratik bir şekilde nasıl ele alacağınızı bilmek, sizi iyi durumda tutacaktır.

İLGİLİ: Linux'ta Başlamak için 9 Bash Komut Dosyası Örneği