awkRozpoczęcie pracy z awk


Uwagi

Nazwa AWK pochodzi od ostatnich inicjałów jej twórców: Alfreda V. Aho, Petera J. Weinbergera i
Brian W. Kernighan.

Zasoby

Wersje

Nazwa Początkowa wersja Wersja Data wydania
POSIX awk 1992 IEEE Std 1003.1, edycja 2013 19.04.2013
Jeden True Awk lub nawk lub BWK awk 198X - 2012-12-20
GNU awk lub gawk 1986 4.1.3 2015-05-19

AWK przez przykłady

AWK to język manipulacji ciągami, używany głównie w systemach UNIX. Ideą AWK było stworzenie uniwersalnego języka do pracy podczas pracy z plikami, który nie był zbyt skomplikowany do zrozumienia.

AWK ma kilka innych wariantów, ale główna koncepcja jest taka sama, tylko z dodatkowymi funkcjami. Te inne warianty to NAWK i GAWK. GAWK zawiera wszystkie funkcje obu, a NAWK jest o krok wyżej niż AWK, jeśli chcesz.

Najprostszym sposobem myślenia o AWK jest uznanie, że ma on 2 główne części. Wzór i działanie.

Prawdopodobnie najbardziej podstawowy przykład AWK: (Zobacz także: Hello World)

BEGIN {print "START"}
      {print        }
END   {print "STOP" }
 

Tutaj słowa kluczowe BEGIN i END są wzorem, podczas gdy akcja znajduje się w {}. Ten przykład byłby bezużyteczny, ale jedynie niewielkie zmiany wymagałyby uczynienia go użyteczną funkcją.

BEGIN {print "File\tAuthor"}
      {print $8, "\t", $3}
END {print " - DONE - "}
 

W tym przypadku \t oznacza znak Tab i służy do wyrównania granic linii wyjściowej. 8 i 3 dolary są podobne do użycia widocznego w Shell Scripts , ale zamiast używać trzeciego i ósmego argumentu, wykorzystuje trzecią i ósmą kolumnę linii wejściowej.

Tak więc w tym przykładzie zostanie wydrukowane: Autor pliku w górnym wierszu, podczas gdy drugi wiersz dotyczy ścieżek do plików. 8 $ to nazwa pliku, 3 $ to właściciel (gdy patrzysz na ścieżkę do katalogu, będzie to bardziej jasne). Na koniec zostanie wydrukowany dolny wiersz, jak można się spodziewać - GOTOWE -

Kredyt za powyższy przykład trafia na http://www.grymoire.com/Unix/Awk.html

Plik referencyjny

coins.txt z Grega Goebela:

gold     1    1986  USA                 American Eagle
gold     1    1908  Austria-Hungary     Franz Josef 100 Korona
silver  10    1981  USA                 ingot
gold     1    1984  Switzerland         ingot
gold     1    1979  RSA                 Krugerrand
gold     0.5  1981  RSA                 Krugerrand
gold     0.1  1986  PRC                 Panda
silver   1    1986  USA                 Liberty dollar
gold     0.25 1986  USA                 Liberty 5-dollar piece
silver   0.5  1986  USA                 Liberty 50-cent piece
silver   1    1987  USA                 Constitution dollar
gold     0.25 1987  USA                 Constitution 5-dollar piece
gold     1    1988  Canada              Maple Leaf
 

Minimalna teoria

Ogólne awk one-liner:

awk <awk program> <file>
 

lub:

<shell-command> | awk <awk program> 
 

<shell-command> i <file> są adresowane jako dane wejściowe awk .

<awk program> to kod następujący po tym szablonie (pojedyncze, nie podwójne, cudzysłowy):

'BEGIN   {<init actions>};
 <cond1> {<program actions>};
 <cond2> {<program actions>};
 ...
 END  {<final actions>}'
 

gdzie:

  • <condX> jest najczęściej wyrażeniem regularnym /re/ , które ma być dopasowane liniami wejściowymi awk;
  • <* actions> to sekwencja instrukcji , podobnych do poleceń powłoki, wyposażonych w konstrukcje podobne do C.

`` jest przetwarzany zgodnie z następującymi zasadami:
  1. BEGIN ... i END ... są opcjonalne i wykonywane przed lub po przetworzeniu linii wejściowych awk.
  2. Jeśli dla każdego wiersza na wejściu awk warunek <condN> to mięso, wykonywany jest powiązany blok <program actions> .
  3. Domyślnie {<program actions>} to {print $0} .

Warunki można łączyć ze standardowymi operatorami logicznymi:

    /gold/ || /USA/ && !/1986/
 

gdzie && ma pierwszeństwo przed || ;

Instrukcja print . print item1 item2 instrukcja print item1 item2 drukuje pozycje na STDOUT.
Elementami mogą być zmienne ( X , $0 ), ciągi znaków („cześć”) lub liczby.
item1, item2 są zestawiane z wartością zmiennej OFS ;
item1 item1 item2 są justapoxed ! Użyj item1 " " item2 do spacji lub printf, aby uzyskać więcej funkcji.

Zmienne nie potrzebują $ , tj .: print myVar;
W awk wbudowane są następujące zmienne specjalne:

  • FS : działa jak separator pól, dzieląc linie wejściowe awk na pola. Mogę być pojedynczym znakiem, FS="c" ; ciąg zerowy, FS="" (wtedy każdy pojedynczy znak staje się oddzielnym polem); wyrażenie regularne bez ukośników, FS="re" ; FS=" " oznacza ciągi spacji i tabulatorów i jest wartością domyślną.
  • NF : liczba pól do odczytania;
  • $1 $2 , ...: 1. pole, 2. pole. itd. bieżącej linii wejściowej,
  • $0 : bieżąca linia wejściowa;
  • NR : numer bieżącej linii put.
  • OFS : ciąg znaków do sortowania pól po wydrukowaniu.
  • ORS : separator rekordów wyjściowych, domyślnie nowy wiersz.
  • RS : Separator linii wejściowej (rekordu). Domyślnie nowa linia. Ustaw jako FS .
  • IGNORECASE : wpływa na FS i RS, gdy są wyrażeniami regularnymi;

Przykłady

Filtruj wiersze według wyrażenia regularnego gold i policz je:

# awk 'BEGIN {print "Coins"} /gold/{i++; print $0}  END {print i " lines out of " NR}' coins.txt
Coins
gold     1    1986  USA                 American Eagle      
gold     1    1908  Austria-Hungary     Franz Josef 100 Korona 
gold     1    1984  Switzerland         ingot 
gold     1    1979  RSA                 Krugerrand 
gold     0.5  1981  RSA                 Krugerrand 
gold     0.1  1986  PRC                 Panda                       
gold     0.25 1986  USA                 Liberty 5-dollar piece
gold     0.25 1987  USA                 Constitution 5-dollar piece
gold     1    1988  Canada              Maple Leaf
9 lines out of 13
 

Domyślne działanie i warunek print $0 oparciu o wewnętrzną zmienną NR awk NR :

# awk 'BEGIN {print "First 3 coins"} NR<4' coins.txt
First 3 coins                                                  
gold     1    1986  USA                 American Eagle         
gold     1    1908  Austria-Hungary     Franz Josef 100 Korona 
silver  10    1981  USA                 ingot
 
Formatowanie za pomocą `printf` w stylu C:
# awk '{printf ("%s \t %3.2f\n", $1, $2)}' coins.txt
gold     1.00                                      
gold     1.00                                      
silver   10.00                                     
gold     1.00                                      
gold     1.00                                      
gold     0.50                                      
gold     0.10                                      
silver   1.00                                      
gold     0.25                                      
silver   0.50                                      
silver   1.00                                      
gold     0.25                                      
gold     1.00
 

Przykłady warunków

awk 'NR % 6'            # prints all lines except those divisible by 6
awk 'NR > 5'            # prints from line 6 onwards (like tail -n +6, or sed '1,5d')
awk '$2 == "foo"'       # prints lines where the second field is "foo"
awk '$2 ~ /re/'         # prints lines where the 2nd field mateches the regex /re/
awk 'NF >= 6'           # prints lines with 6 or more fields
awk '/foo/ && !/bar/'   # prints lines that match /foo/ but not /bar/
awk '/foo/ || /bar/'    # prints lines that match /foo/ or /bar/ (like grep -e 'foo' -e 'bar')
awk '/foo/,/bar/'       # prints from line matching /foo/ to line matching /bar/, inclusive
awk 'NF'                # prints only nonempty lines (or: removes empty lines, where NF==0)
awk 'NF--'              # removes last field and prints the line
 

Dodając akcję {...} można wydrukować określone pole, a nie całą linię, np .:

awk '$2 ~ /re/{print $3 " " $4}'
 

wypisuje trzecie i czwarte pole linii, gdzie drugie pole odpowiada wyrażeniu regularnemu / re /.

Niektóre funkcje łańcuchowe

funkcja substr() :

# awk '{print substr($3,3) " " substr($4,1,3)}' 
86 USA                                            
08 Aus                                            
81 USA                                            
84 Swi                                            
79 RSA                                            
81 RSA                                            
86 PRC                                            
86 USA                                            
86 USA                                            
86 USA                                            
87 USA                                            
87 USA                                            
88 Can                                            
 

match(s, r [, arr]) zwraca pozycję s gdzie występuje wyrażenie regularne r i ustawia wartości RSTART i RLENGTH . Jeśli podany jest argument arr , zwraca tablicę arr której elementy są ustawione dla dopasowanego podwyrażenia w nawiasie. Dopasowania 0-tego elementu arr są ustawione na całe dopasowanie wyrażenia regularnego. Również wyrażenia arr[n, "start"] i arr[n, "length"] zapewniają pozycję początkową i długość każdego pasującego podciągu.

Więcej funkcji ciągów:

sub(/regexp/, "newstring"[, target])
gsub(/regexp/, "newstring"[, target])
toupper("string")
tolower("string")
 

Sprawozdania

Proste oświadczenie to często dowolna z następujących czynności:

variable = expression 
print [ expression-list ] 
printf format [ , expression-list ] 
next # skip remaining patterns on this input line
exit # skip the rest of the input
 

Jeśli stat1 i stat2 są instrukcjami, następujące są również instrukcje:

{stat}

{stat1;  stat2}

{stat1 
stat2}

if ( conditional ) statement [ else statement ]
 

Następujące standardowe konstrukcje typu C są instrukcjami:

if ( conditional ) statement [ else statement ]
while ( conditional ) statement
for ( expression ; conditional ; expression ) statement
break    # usual C meaning 
continue # usual C meaning 
 

Pętla w stylu C do drukowania elementu opisu o zmiennej długości, zaczynając od pola 4:

# awk '{out=""; for(i=4;i<=NF;i++){out=out" "$i}; print out}' coins.txt
USA American Eagle                    
Austria-Hungary Franz Josef 100 Korona
USA ingot                             
Switzerland ingot                     
RSA Krugerrand                        
RSA Krugerrand                        
PRC Panda                             
USA Liberty dollar                    
USA Liberty 5-dollar piece            
USA Liberty 50-cent piece             
USA Constitution dollar               
USA Constitution 5-dollar piece       
Canada Maple Leaf
 

Zauważ, że i jest inicjowane na 0.

Jeżeli warunki i obliczenia zastosowano do pól nuneric:

# awk '/gold/ {if($3<1980) print $0 "$" 425*$2}' coins.txt    
gold     1    1908  Austria-Hungary     Franz Josef 100 Korona      $425
gold     1    1979  RSA                 Krugerrand                  $425   
 

Skrypt wykonywalny AWK

#!/usr/bin/gawk -f
# This is a comment
(pattern) {action}
...
 

Przekazywanie zmiennych powłoki

# var="hello"
# awk -v x="$var" 'BEGIN {print x}'
hello
 

Witaj świecie

Przykład Hello world jest tak prosty, jak:

awk 'BEGIN {print "Hello world"}'
 

Najbardziej podstawowy program awk składa się z prawdziwej wartości (zazwyczaj 1 ) i sprawia, że awk echo wprowadza:

$ date | awk '1'
Mon Jul 25 11:12:05 CEST 2016
 

Ponieważ „witaj świecie” jest również prawdziwą wartością, możesz również powiedzieć:

$ date | awk '"hello world"'
Mon Jul 25 11:12:05 CEST 2016
 

Jednak twoje intencje stają się znacznie wyraźniejsze, jeśli piszesz

$ date | awk '{print}'
Mon Jul 25 11:12:05 CEST 2016
 

zamiast.

Jak uruchamiać programy AWK

Jeśli program jest krótki, możesz dołączyć go do polecenia uruchamiającego awk:

awk -F: '{print $1, $2}' /etc/passwd
 

W tym przykładzie, używając przełącznika wiersza polecenia -F: zalecamy awk użycie: jako separatora pól wejściowych. Jest taki sam jak

awk 'BEGIN{FS=":"}{print $1,$2}' file
 

Alternatywnie możemy zapisać cały kod awk w pliku awk i wywołać ten program awk w następujący sposób:

awk -f 'program.awk' input-file1 input-file2 ...
 

program.awk może być dowolnym programem wielowierszowym, tj .:

# file print_fields.awk
BEGIN {print "this is a header"; FS=":"}
{print $1, $2}
END {print "that was it"}
 

A następnie uruchom go z:

awk -f print_fields.awk /etc/passwd   #-f advises awk which program file to load
 

Lub bardziej ogólnie:

awk -f program-file input-file1 input-file2 ...
 

Zaletą posiadania programu w osobnym pliku jest to, że możesz napisać program z poprawną identyfikacją, aby mieć sens, możesz dołączyć komentarze za pomocą # itp.