15 Şubat 2022 Salı

awk komutu - Dosyayı Sütün Haline Getirir

Giriş
awk ile dosyayı sütunlardan ibaretmiş gibi düşünmek gerekir. Sütun numaraları 1'den başlar. 
- Birinci "/" karakterinden sonra aradığımız şeyi belirtiriz. 
- İkinci "/" karakterinden sonra da eşleşme varsa ne yapmak istediğimizi belirtiriz.

Regular Expression
Açıklaması şöyle. awk her zaman Posix extended regex kullanır
The awk utility shall make use of the extended regular expression notation [...]
...
The sed utility always uses POSIX basic regular expressions unless you use it with its (so far) non-standard but fairly commonly available -E option. 

The grep utility also defaults to POSIX basic regular expressions, but the -E option that enables it to use POSIX extended regular expressions is actually standard (while -P for Perl-compatible regular expressions, PCRE, is non-standard and not commonly implemented on non-GNU systems). 

The grep utility can additionally interpret the given expressions as plain strings with its standard -F option.
awk vs grep
Awk ile içinde bir kelime geçen satırın 4. alanını bulmak grep ile bulmaya göre çok daha kolay

Örnek
Şöyle yaparız
$ awk '/received/{print $4}'
vs
$ grep -oP '\d+(?= received,)'
awk ve Sütün Değerini Karşılaştırma
Açıklaması şöyle. Yani sütun değeri string ise ve karşılaştırılan değer sayı ise her şey önce string'e çevrilir.
When comparing operands of mixed types, numeric operands are converted to strings using the value of CONVFMT
Örnek
Elimizde şöyle bir veri olsun
Chen Cho 5/19/63 203-344-1234 $76
Tom Billy 4/12/45 913-972-4536 $102
Larry White 11/2/54 908-657-2389 $54
Bill Clinton 1/14/60 654-576-4114 $201
Steve Ann 9/15/71 202-545-8899 $58
Şöyle yaparız
awk '$4 < 40' employees
Çıktı olarak şunu alırız. Çünkü sütun değeri bir string, 40 ise bir sayı. 40 önce string'e çevrilir, daha sonra karşılaştırma yapılır. Bu durumda 9 le başlayan değerler 4'ten küçük olduğu için çıktıya dahil olmazlar.
203-344-1234
202-545-8899
Örnek
Şöyle yaparız. Burada birinci sütun Uptime kelimesi olan, üçüncü sütunun değeri de 100'den büyük olan satırları görebiliriz
awk '$1 == "Uptime" && $3 > 100 {print}' file1
Dosya ve çıktısı şöyledir
Uptime is 172 days
Uptime is 562 days
Uptime is 30 days
downtime is 197 days

# Çıktı
Uptime is 172 days
Uptime is 562 days
Sütun Numarasına Göre - NF Değişkeni
Örnek
Şöyle yaparız
#Print all lines in file with more or less than three fields. 
awk -F'\t' 'NF!=3' file

#To limit to only more than three fields, use:
awk -F'\t' 'NF>3' file
Satır Numarasına Göre - FNR Değişkeni 
Örnek - Belli Bir Satıra Bakmak
İkinci satırda "Category X" geçen dosyaları bulmak için şöyle yaparız
awk 'FNR == 2 && /Category X/ {print FILENAME}' *
Eğer dosyanın devamına bakmak istemiyorsak ki bu durumda gerek yok ve de awk sürümümüz destekliyorsa "nextfile" kullanılabilir. Şöyle yaparız
awk 'FNR==2{ if (/Category X/) print FILENAME; nextfile }' *
Açıklaması şöyle
... the use of nextfile (if your awk supports it - many do, some don't) will cause awk to stop reading the current file and move on to the next one once the 2nd line is read.
NR (number of records ) Değişkeni 
O ana kadar işlenen toplam satır sayısını verir.
Örnek
Şöyle yaparız. Burada dosya değişince FNR tekrar başa dönüyor ama NR artmaya devam ediyor.
$ cat file1
a
b
c

$ cat file2
d
e

$ awk '{print FILENAME, NR, FNR, $0}' file1 file2
file1 1 1 a
file1 2 2 b
file1 3 3 c
file2 4 1 d
file2 5 2 e
Örnek
Şöyle yaparız. FNR ile satır numarası 1 ise ve ilk dosya değilse "---" string'i basılıyor
awk 'FNR==1 && NR!=1  {print "---"}{print}' /<my_directory>/*.yaml | ...
BeforeAfterMatch
Bir eşleşmeden sonra gelen N'inci satıra erişmek içindir. Örnekler burada

Örnek
Şöyle yaparız. Burada phrase ile aranılan şey belirtiliyor. Eşleşmeden sonra gelen 3. satırdaki karakter değiştiriliyor.
awk 'c&&!--c {gsub(/r/,"ɹ")} /\\phrase/ {c=3} 1' file > newfile