Split Komutu Kullanımı
AWK ve SED komutlarıyla yaptığımız değişikliklerin ardından, yine HEAD ve TAIL komutlarını da dahil ederek yeni bir komut ile metin, dosya ve dosya içeriği işlemlerini genişletmek istiyorum.
Bu vesileyle ele alacağımız komutumuz; Split ve dosyaları istediğimiz boyuttaki parçalara bölmemizi mümkün kılmakta. Komut ile ilgili detaylara geçelim.
Split Komutu ve Kullanımı
Split, Unix temelli işletim sistemlerinde dosyaları parçalara bölmemizi sağlayan, oldukça pratik bir kullanıma sahip bir komuttur. Ancak, bazı temel sınırları vardır. Örneğin, işlemi doğrudan dosya içeriğini temle alarak gerçekleştirdiği için CSV gibi dosyalarda yer alabilecek başlıkları (header) da yığının bir parçası olarak değerlendirir. Bu gibi durumlarda diğer komutların desteği ile daha kapsamlı çözümler üretilebilir. Bu konuya örnekler bölümünde değineceğim. Öncelikle komutumuzun en temel kullanım biçimine bakalım:
split [opsiyonlar]... [giriş [ekler]]
Bu arada, split komutu eğer parça ifadesi komut içerisinde belirtilmezse dosyaları ön tanımlı değer olan 1000 satır üzerinden bölecektir. Örnek işlemlerde Emissions Data.csv
içeriğini kullanacağım1. Dosya içeriğine dair ön bilgilerimizi edinelim.
ls -l Emissions_Data.csv
wc -l Emissions_Data.csv
head Emissions_Data.csv
Dosya boyutu ~28Kb ve içeriğinde başlıklar hariç 788 satır barındırmakta. İlk satır ise Year, Country, Continent ve Emission başlıklarından (head -1
) oluşuyor. Yazının giriş bölümlerinde de bahsi geçtiği üzere split işleminde bu başlıkları işlemin dışında tutmak isteyebiliriz. Bu maksatla tail komutu işimize yarayabilir.
tail -n 788 Emissions_Data.csv > Emissions_Data_New.csv
İşlemlerimizi başlıkların olmadığı Emissions_Data_New.csv
dosyası üzerinden gerçekleştirebiliriz.
-a N, –suffix-length=N
-a
(veya --suffix-length
) bize uzantı-ek tanımlama imkanı sunmakta. split
komutunu herhangi bir option olmaksızın kullandığımızda parçaların adlandırılması xaa
gibi biçimlerde olacaktır. Bu isimlendirmedeki aa
-a
tarafından belirlenir ve ön tanımlı olarak 2 değerine sahiptir. Diğer yandan, isim belirtilmediği sürece isimlendirme x ile başlayacaktır.
split -a 5 Emissions_Data_New.csv
Yukarıdaki komu komut satırı arayüzü üzerinden uyguladığımızda oluşturulacak dosya adı xaaaaa
şeklinde olacaktır. Bir diğer örnekte -a
kullanımına ek olarak satır sayısı da verelim ve isimlendirmenin nasıl sürdüğünü görelim. Hatırlarsanız wc -l
komutu ile satır sayısının 788 olduğu bilgisini almıştık.
-l NUMBER, –lines=NUMBER
split -a 5 -l 100 Emissions_Data_New.csv
Yukarıdaki komutu uygulamamızın ardından her birinde maksimum 100 satır bulunan 8 adet dosya oluşacaktır ve bu dosyaların isimlendirmeleri xaaaaa, xaaaab, xaaaac, ..., xaaaah
şeklinde ilerleyecektir. split
isimlendirmeyi her dosya için son karakter a’dan başlayacak şekilde dıştan içe doğru yürütür. ls -l
ile dosya boyutumuzun ~27Kb (27364 bytes) olduğu bilgisine sahibiz. Dosyamızı 10Kb’lik parçalara bölmek isteyebiliriz. Unutmadan, dosya boyutunda unutulmaması gereken konu bir satırın pek çok sütundan oluşması ihtimalinde satır sayısı az olsa da dosya boyutu yüksek olabilir.
-b SIZE, –bytes=SIZE
split -a 1 -b 10000 Emissions_Data_New.csv new
Komutu uyguladığımızda, newa, newb, newc
isimli 3 adet dosya üretilecektir. Ek bir not, dosya isimlendirilmesindeki sıralama sayesinde dosyalarımızı kolaylıkla birleştirebiliriz.
cat new* > Emissions_Data.csv
Örneklerimizi biraz daha geliştirelim. Örneklendirme öncesinde başlıkları (header) alanını hariç tutarak yeni bir dosya oluşturmuş ve işlemlerimizi doğrudan bu dosya üzerinden gerçekleştirmiştik. Peki, yeni bir dosya oluşturmadan işlemlerimizi yapmak ve çıktıları bu başlıklar olmadan oluşturmak istersek ne yapmalıyız?
splitCsv() {
HEADER=$(head -1 $1)
if [ -n "$2" ]; then
CHUNK=$2
else
CHUNK=1000
fi
tail -n +2 $1 | split -l $CHUNK - $1_split_
for i in $1_split_*; do
echo -e "$HEADER\n$(cat $i)" > $i
done
}
Yukarıdaki komut stackoverflow üzerinde paylaşılmış bir soruya istinaden2 üretilen bir fonksiyondan oluşmakta. splitCsv()
fonksiyonunu komut satırı arayüzü üzerinden uyguladığımızda splitCsv Emissions_Data.csv
şeklinde kullanabiliriz.
splitCsv Emissions_Data_New.csv
Yukarıdaki komutu uyguladığımızda splitCsv
fonksiyonu içerisindeki tanımlamalar çerçevesinde (CHUNK=1000
(satır sayısı) ve _split_
isim eki gibi) dosyalar başlıksız olarak üretilecektir. Yukarıdaki komutu uygulayıp, ilgili fonksiyonu çağırdığımızda satır sayısı 1000’den düşük olduğu için tek dosya üretilecektir. Ancak, satır sayısı belirterek de ($2
) işlem yürütebilmekteyiz.
splitCsv Emissions_Data_New.csv 300
Oluşturulacak dosyalar newData.csv_split_aa, newData.csv_split_ab, newData.csv_split_ac
şeklinde adlandırılacaklardır. Fonksiyon içeriğini satır yerine (-l
) dosya boyutu (-b
) temel alınacak şekilde de düzenleyebilirsiniz. İlgili işlemi AWK komutu ile gerçekleştirmek için aşağıdaki komutu uygulayabilirsiniz3.
awk -v l=500 '(NR==1){header=$0;next}
(NR%l==2) {
c=sprintf("%0.5d",c+1);
close(file); file=FILENAME; sub(/csv$/,c".csv",file)
print header > file
}
{print $0 > file}' Emissions_Data.csv
Bu komut uygulandığında, oluşturulan dosyalar newData.00001.csv, newData.00002.csv ve newData.00003.csv şeklinde isimlendirileceklerdir.
Bir diğer örnekte ise, başlıkları (Year, Country, Continent ve Emission) oluşturulan her dosyanın ilk satırına ekleyelim4.
splitWithHeader() {
HEADER=$(head -1 $1)
if [ -n "$2" ]; then
CHUNK=$2
else
CHUNK=500
fi
tail -n +2 $1 | split -l $CHUNK - split_
for file in split_*
do
head -n 1 $1 > tmp_file
cat $file >> tmp_file
mv -f tmp_file $file
done
}
Yukarıdaki splitWithHeader()
fonksiyonu ile belirttiğimiz dosya standart değerler dışında (CHUNK=1000
ve split_
isim eki) bir değer tanımlanmamışsa belirtilen dosyayı (Emissions_Data.csv) en fazla 500 satır içerecek şekilde parçalara bölecek ve her parça için split_aa, split_ab
şeklinde isimlendirmeler oluşturacaktır. Bu dosyaları görüntülediğinizde her dosyanın ilk satırında Year, Country, Continent ve Emission başlıklarının da olduğunu görebilirsiniz.
Split komutu örneklerde de görüldüğü üzere oldukça basit bir kullanıma sahip. Komut ile ilgili daha detaylı bilgi almak için her zaman olduğu gibi man split
komutunu kullanabiliriz. Ek olarak, standart split
komutu dışında benzer işlemleri çok daha kapsamlı option seçenekleriyle birlikte csplit
ile de gerçekleştirmek mümkün.
- plotly/datasets. (2016). Emissions Data.csv ↩
- Pawan Mude. (2013). How to split CSV files as per number of rows specified?. StackOverflow ↩
- neisantos. (2018). Split CSV files into smaller files but keeping the headers?. StackOverflow ↩
- Edmond Commerce. (2009). Linux Split File (eg CSV) and Keep Header Row ↩