Nowe posty

Autor Wątek: awk :/  (Przeczytany 8700 razy)

MaxUbu

  • Gość
awk :/
« dnia: 2008-09-15, 01:01:59 »
Mam plik tekstowy z 3 kolumnami, który ostatecznie ma być sformatowany na 6 kolumn. Pierwsza kolumna to string, dwie kolejne to ciągi liczbowe które po przemnożeniu mają wypełnić pozostałe 3 kolumny (już przez operacje w awk).  Mój kod to:
BEGIN   {FS = "t"    
printf "%s %6s %8s %6s %6s %9s\\n", "NAME", "RATE", "HOURS", "BASE", "TAX", "NETPAY" }  
{printf "%s %6d %7d %7d\\n", $1, $2, $3, $4 , $5, $6
base = base + $2 * $3}

END     {printf "\\n%10s %6d %5d\\n", "BASE", base}
Lecz nie daje on żadnego wyniku w sformatowanej kolumnie. Czy mogę chociaż prosić o podpowiedź jak się do tego zabrać? Albo pokazać gdzie jest problem?
Z góry bardzo dziękuję.

arctgx: http://forum.linux.pl/help.php#bbcode

arctgx

  • Gość
awk :/
« Odpowiedź #1 dnia: 2008-09-15, 02:05:46 »
Nie wiem czym różni się %s od np. %6s i nie wnikam w to, zakładając że to tylko sposób formatowania wyników.

Na pierwszy rzut oka, wnikania tym razem w sendo, dziwię się, czym są $4, $5 i $6, kiedy plik wejściowy ma tylko trzy kolumny. Nie dziwię się za to, jeśli ze względu na ich nieistnienie dostajesz pustkę. Chyba zamiast nich chciałbyś coś wrzucić?

Klamrowy nawias z mnożeniem to instrukcja mówiąca, co robić z każdym wierszem wejściowego pliku. Nie ma na tym etapie żadnej operacji na kolumnach (przypisania którejkolwiek z nich czegokolwiek). Tylko jedna zmienna base sobie pracuje na wynik, który chcesz wyświetlić po przeczytaniu wszystkich wierszy.

Nawiasem, zamiast base = base + $2 * $3 można krócej base+=$2*$3.

xavery

  • Gość
awk :/
« Odpowiedź #2 dnia: 2008-09-15, 10:53:13 »
Zmienna FS określa wejściowy separator pól. Wątpię czy separatorem w pliku jest litera "t". Prędzej jest to tabulacja czyli "\\t" ale awk domyślnie dzieli pola według białych znaków więc redifiniowanie tej zmiennej w ten sposób jest raczej wątpliwe.
W bloku przetwarzającym linie pliku dajesz w printf specyfikacje czterech argumentów (tych ze znakami "%") a w dalszych argumentach przypisujesz sześć zmiennych, spośród których, jak słusznie zauważył Arctgx, istnieje połowa (brak jest zmiennych $4, $5, $6 bo plik ma tylko trzy pola wejściowe). Jeśli chcesz osiągnąć cel to powinieneś skonstruować printf mniej więcej w takiej postaci:

printf ("%s %s %s %s %s %s\\n",$1, $2, $3, $1*$2, $3*$1, $2*$3);

A tak naprawdę to można użyć funkcji print mniej więcej tak:

print $1, $2, $3, $1*$2, $3*$1, $2*$3;

Tylko oczywiście masz bardziej ograniczone możliwości formatowania.

Tak na marginesie - nie warto podawać specyfikacji szerokości pola w postaci "%6s" ponieważ i tak zostanie ono automatycznie dobrane. Zamiast tego lepiej stosować wyrównanie do lewej czyli te same cyferki lecz z minusami: "%-6s"

MaxUbu

  • Gość
awk :/
« Odpowiedź #3 dnia: 2008-09-15, 22:13:42 »
Dzięki za podpowiedzi mój kod wygląda teraz tak:

BEGIN   {FS = "t"    
   printf "%s %6s %8s %6s %6s %9s\\n", "NAME", "RATE", "HOURS", "BASE", "TAX", "NETPAY"}  
    {printf "%s %6d %7d %7d\\n",$1, $2, $3, $2*$3, $2*$3*20%, $2*$3*80%}
END     {printf "\\n"}
Niestety tak wygląda output
$ awk -f try em
NAME   RATE   HOURS   TAX   NETPAY
Jones   10   30   0   0
Bryne   12   25   0   0
Allen   12   28   0   0
Ryan   8   15   0   0
Green   10   20   0   0
Black   12   37   0   0
Tyson   10   18   0   0
Kelly   8   13   0   0
Shelly   10   26   0   0
Burn   12   16   0   0
Pomimo ustalenia zmiennych wyniki operacji na zmiennych się nie pojawiają. Czy jest to wina źle ustawionych zmiennych? Czy operacji na nich wykonywanych?
Ogólnie to ma być wyliczenie uproszczonej listy płac gdzie base to podstawa, tax to naliczony podatek, a netpay to wynagrodzenie netto.  W pliku wsadowym $1 to imię i nazwisko, $2 stawka za h, a $3 liczba przepracowanych godzin.
Dzięki za wszelkie komentarze i pomoc

MaxUbu

  • Gość
awk :/
« Odpowiedź #4 dnia: 2008-09-15, 22:15:43 »
A dodam jeszcze że formatowanie jest ok tylko tu jakoś dziwnie się wkleiło

arctgx

  • Gość
awk :/
« Odpowiedź #5 dnia: 2008-09-15, 23:05:35 »
Wkleiło się, bo nie przeczytałeś mojego komentarza w swoim wątku.