man/text
man · Metin İşleme

$ awk

Bölüm 1 · Metin İşleme

kalıp odaklı tarama ve işleme dili

Özet

awk [ -F fs ] [ -v var=değer ] [ 'prog' | -f progdosyası ] [ dosya ... ]

Açıklama

awk, literal olarak prog içinde veya -f progdosyası ile belirtilen bir ya da daha fazla dosyada tanımlanan kalıp kümesiyle eşleşen satırlar için her girdi dosyasını tarar. Her kalıpla ilişkili olarak, bir dosyanın satırı kalıpla eşleştiğinde gerçekleştirilecek bir eylem bulunabilir.

Her satır, her kalıp-eylem ifadesinin kalıp kısmıyla karşılaştırılır; eşleşen her kalıp için ilişkili eylem çalıştırılır. Dosya adı olarak -, standart girişi temsil eder.

var=değer biçimindeki herhangi bir dosya argümanı, dosya adı olarak değil atama olarak kabul edilir ve bir dosya adı olsaydı açılacağı noktada yürütülür. -v var=değer, prog yürütülmeden önce yapılacak bir atamadır; herhangi bir sayıda -v seçeneği kullanılabilir.

-F fs, girdi alanı ayırıcısını fs düzenli ifadesi olarak tanımlar.

Bir girdi satırı normalde boşluklarla veya FS düzenli ifadesiyle ayrılmış alanlardan oluşur. Alanlar $1, $2, ... biçiminde gösterilir; $0 tüm satırı temsil eder. FS boşsa, girdi satırı karakter başına bir alan olacak şekilde bölünür.

Program Yapısı

Bir kalıp-eylem ifadesi şu biçime sahiptir:

kalıp { eylem }

Eksik { eylem }, satırı yazdırmak anlamına gelir. Eksik kalıp her zaman eşleşir. Kalıp-eylem ifadeleri satır sonları veya noktalı virgüllerle ayrılır.

Eylemler

Bir eylem, ifadelerden oluşan bir dizidir. Bir ifade aşağıdaki biçimlerden biri olabilir:

if (expression) statement [else statement]
while (expression) statement
for (expression; expression; expression) statement
for (var in array) statement
do statement while (expression)
break
continue
{ [ statement ... ] }
expression                    # genellikle var = expression
print [ expression-list ] [ > expression ]
printf format [ , expression-list ] [ > expression ]
return [ expression ]
next                          # bu girdi satırındaki kalan kalıpları atla
nextfile                      # bu dosyanın kalanını atla, sonrakini aç ve baştan başla
delete array[ expression ]    # bir dizi öğesini sil
delete array                  # dizinin tüm öğelerini sil
exit [ expression ]           # hemen çık; durum kodu expression değeridir

İfadeler noktalı virgül, satır sonu veya sağ süslü parantezle sonlandırılır. Boş bir expression-list, $0 anlamına gelir.

Dize sabitleri çift tırnak içine alınır ve olağan C kaçış dizileri tanınır. İfadeler bağlama göre dize veya sayısal değer alır; +, -, *, /, %, ^ ve birleştirme operatörleriyle oluşturulur. !, ++, --, +=, -=, *=, /=, %=, ^=, >, >=, <, <=, ==, != ve ?: operatörleri de ifadelerde kullanılabilir.

Değişkenler skalerler, dizi öğeleri (x[i]) veya alanlar olabilir. Değişkenler boş dizeye sıfırlanır. Dizi indisleri sayısal olmak zorunda değildir; herhangi bir dize olabilirler. Bu, ilişkisel bellek (associative memory) benzeri bir kullanım sağlar. [i,j,k] gibi çoklu indisler kabul edilir; bileşenler SUBSEP değeriyle ayrılarak birleştirilir.

Çıktı

print, argümanlarını standart çıktıya yazar. > dosya veya >> dosya varsa çıktıyı bir dosyaya, | cmd varsa bir boruya yönlendirir. Argümanlar mevcut çıktı alanı ayırıcısıyla ayrılır ve çıktı kayıt ayırıcısıyla sonlandırılır.

dosya ve cmd, literal adlar veya parantez içindeki ifadeler olabilir. Farklı ifadelerdeki aynı dize değerleri aynı açık dosyayı gösterir.

printf, ifade listesini verilen biçime göre biçimlendirir; ayrıntılar için printf(3) sayfasına bakın. Yerleşik close(expr) fonksiyonu expr dosyasını veya borusunu kapatır. Yerleşik fflush(expr) fonksiyonu expr dosyası veya borusu için arabelleğe alınmış tüm çıktıyı boşaltır.

Yerleşik Fonksiyonlar

atan2, cos, exp, log, sin ve sqrt matematiksel fonksiyonları yerleşiktir.

  • length: Dize olarak alınan argümanının uzunluğunu, dizi argümanı için dizideki öğe sayısını veya argüman yoksa $0 uzunluğunu döndürür.
  • rand: [0,1) aralığında rastgele sayı döndürür.
  • srand: rand için tohum (seed) değerini ayarlar ve önceki tohum değerini döndürür.
  • int: Bir değeri tam sayıya kırpar.
  • substr(s, m [, n]): s dizisinin 1'den başlanarak sayılan m konumundan başlayan n karakterlik alt dizesini döndürür. n yoksa dizinin geri kalanını kullanır.
  • index(s, t): t dizisinin s içinde göründüğü konumu döndürür; yoksa 0 döndürür.
  • match(s, r): r düzenli ifadesinin s içinde göründüğü konumu döndürür; yoksa 0 döndürür. RSTART ve RLENGTH, eşleşen dizenin konumuna ve uzunluğuna ayarlanır.
  • split(s, a [, fs]): s dizisini a[1], a[2], ..., a[n] dizi öğelerine böler ve n değerini döndürür. Bölme işlemi fs düzenli ifadesiyle veya fs verilmemişse FS alan ayırıcısıyla yapılır. Alan ayırıcısı boş dizeyse, dize karakter başına bir dizi öğesi olacak şekilde bölünür.
  • sub(r, t [, s]): s dizisindeki r düzenli ifadesinin ilk oluşumunu t ile değiştirir. s verilmemişse $0 kullanılır.
  • gsub(r, t [, s]): Düzenli ifadenin tüm oluşumlarını değiştirmesi dışında sub ile aynıdır. sub ve gsub, yapılan değişikliklerin sayısını döndürür.
  • sprintf(fmt, expr, ...): expr ... ifadelerinin fmt biçimine göre biçimlendirilmesiyle elde edilen dizeyi döndürür; ayrıntılar için printf(3) sayfasına bakın.
  • system(cmd): cmd komutunu yürütür ve çıkış durumunu döndürür. Hata durumunda -1, normal çıkışta cmd çıkış durumu, sinyalle sonlandırmada 256 + sig, bellek dökümü varsa 512 + sig döndürür.
  • tolower(str): str dizisinin tüm büyük harfli karakterlerini karşılık gelen küçük harfli eşdeğerlerine dönüştürülmüş olarak döndürür.
  • toupper(str): str dizisinin tüm küçük harfli karakterlerini karşılık gelen büyük harfli eşdeğerlerine dönüştürülmüş olarak döndürür.

getline

getline, $0 değerini mevcut girdi dosyasındaki bir sonraki girdi kaydına ayarlar. getline < dosya, $0 değerini dosya içindeki bir sonraki kayda ayarlar.

getline x, bunun yerine x değişkenini ayarlar. cmd | getline, cmd çıktısını getline içine yönlendirir; getline için her çağrı, cmd çıktısındaki bir sonraki satırı döndürür.

Tüm durumlarda getline, başarılı giriş için 1, dosya sonu için 0, hata için -1 döndürür.

Kalıplar

Kalıplar, düzenli ifadelerin ve ilişkisel ifadelerin !, || ve && ile oluşturulan isteğe bağlı Boolean kombinasyonlarıdır. Düzenli ifadeler re_format(7) içinde tanımlandığı gibidir.

Bir kalıptaki izole düzenli ifadeler tüm satıra uygulanır. Düzenli ifadeler, ~ ve !~ operatörleri kullanılarak ilişkisel ifadelerde de yer alabilir. /re/ sabit bir düzenli ifadedir; bir kalıptaki izole düzenli ifade konumu dışında, herhangi bir dize (sabit veya değişken) düzenli ifade olarak kullanılabilir.

Bir kalıp, virgülle ayrılmış iki kalıptan oluşabilir. Bu durumda eylem, ilk kalıbın oluşumundan ikincinin oluşumuna kadar olan tüm satırlar için gerçekleştirilir.

İlişkisel ifade biçimleri:

expression matchop regular-expression
expression relop expression
expression in array-name
(expr, expr, ...) in array-name

Burada relop, C'deki altı ilişkisel operatörden herhangi biridir; matchop, ~ (eşleşir) veya !~ (eşleşmez) operatörlerinden biridir. Koşul ifadesi aritmetik ifade, ilişkisel ifade veya bunların Boolean kombinasyonu olabilir.

Özel Kalıplar

BEGIN ve END, ilk girdi satırı okunmadan önce ve son satır okunduktan sonra kontrolü ele geçirmek için kullanılır. BEGIN ve END diğer kalıplarla birleşmez.

BEGIN ve END bir programda birden çok kez görünebilir; awk bunları okuduğu sırayla yürütür.

Özel Değişkenler

  • ARGC: Argüman sayısı; atanabilir.
  • ARGV: Argüman dizisi; atanabilir. Null olmayan üyeler dosya adı olarak alınır.
  • CONVFMT: Sayıları dönüştürürken kullanılan dönüştürme biçimi. Varsayılan değer %.6g şeklindedir.
  • ENVIRON: Ortam değişkenleri dizisi; indisler isimlerdir.
  • FILENAME: Mevcut girdi dosyasının adı.
  • FNR: Mevcut dosyadaki mevcut kaydın sıra numarası.
  • FS: Alanları ayırmak için kullanılan düzenli ifade; -Ffs seçeneğiyle de ayarlanabilir.
  • NF: Mevcut kayıttaki alan sayısı.
  • NR: Mevcut kaydın sıra numarası.
  • OFMT: Sayılar için çıktı biçimi. Varsayılan değer %.6g şeklindedir.
  • OFS: Çıktı alanı ayırıcısı. Varsayılan değer boşluktur.
  • ORS: Çıktı kayıt ayırıcısı. Varsayılan değer satır sonudur.
  • RLENGTH: match tarafından eşleşen dizenin uzunluğu.
  • RS: Girdi kayıt ayırıcısı. Varsayılan değer satır sonudur. Boşsa, boş satırlar kayıtları ayırır. Birden fazla karakter uzunluğundaysa RS düzenli ifade olarak kabul edilir ve kayıtlar bu ifadeyle eşleşen metinle ayrılır.
  • RSTART: match tarafından eşleşen dizenin başlangıç konumu.
  • SUBSEP: Çoklu indisleri ayırır. Varsayılan değer 034 şeklindedir.

Fonksiyonlar

Fonksiyonlar, kalıp-eylem ifadesi konumunda şu şekilde tanımlanabilir:

function foo(a, b, c) { ...; return x }

Parametreler skaler ise değerle (by value), dizi adı ise referansla (by reference) geçirilir. Fonksiyonlar özyinelemeli (recursive) olarak çağrılabilir.

Parametreler fonksiyona yereldir; diğer tüm değişkenler küreseldir. Bu nedenle, fonksiyon tanımında fazladan parametreler sağlayarak yerel değişkenler oluşturulabilir.

Ortam Değişkenleri

  • POSIXLY_CORRECT: Ortamda ayarlanmışsa awk, ardışık ters eğik çizgiler ve ampersanlar açısından sub ve gsub için POSIX kurallarını izler.

Örnekler

72 karakterden uzun satırları yazdırmak:

length($0) > 72

İlk iki alanı ters sırada yazdırmak:

{ print $2, $1 }

Girdi alanları virgül ve/veya boşluklar ve sekmelerle ayrılmışken ilk iki alanı ters sırada yazdırmak:

BEGIN { FS = ",[ \t]*|[ \t]+" }
{ print $2, $1 }

İlk sütunu toplamak, toplamı ve ortalamayı yazdırmak:

{ s += $1 }
END { print "toplam", s, " ortalama", s/NR }

start ve stop çiftleri arasındaki tüm satırları yazdırmak:

/start/, /stop/

echo(1) komutunu simüle etmek:

BEGIN {
    for (i = 1; i < ARGC; i++) printf "%s ", ARGV[i]
    printf "\n"
    exit
}

Ayrıca Bakınız

grep(1), lex(1), sed(1)

A. V. Aho, B. W. Kernighan, P. J. Weinberger, The AWK Programming Language, Addison-Wesley, 1988. ISBN 0-201-07981-X.

Hatalar

Sayılar ve dizeler arasında açık dönüşümler yoktur. Bir ifadenin sayı olarak ele alınmasını zorlamak için ona 0 ekleyin; dize olarak ele alınmasını zorlamak için ona "" birleştirin.

Fonksiyonlardaki değişkenler için kapsam kuralları karışıktır; sözdizimi ise daha kötüdür.

Yalnızca sekiz bitlik karakter kümeleri doğru şekilde işlenir.