Mam plik danych, który chcę znormalizować awk
na podstawie ostatniego punktu danych. Dlatego najpierw chciałbym uzyskać dostęp do ostatniego punktu danych, aby znormalizować dane, a następnie przetwarzać normalnie.
Poniższa metoda, wykorzystująca tac
dwa razy, spełnia swoje zadanie, ale może jest bardziej skomplikowana niż to konieczne.
$ cat file
0 5
1 2
2 3
3 4
$ tac file | awk 'NR==1{norm=$2} {print $1, $2/norm}' | tac
0 1.25
1 0.5
2 0.75
3 1
Moje pytanie brzmi: czy można uzyskać powyższy wynik, używając tylko awk?
Myślę, że odpowiedź brzmi „Nie, awk skanuje plik linia po linii”, ale jestem otwarty na sugestie dotyczące alternatyw.
źródło
$ awk --version GNU Awk 3.1.8
. Czy możesz dodać bardzo małe wyjaśnienie, w jaki sposób obsługiwane są dwa pliki wejściowe i co tonext
robi?Jeśli twoje źródło danych jest plikiem, który można odczytać wiele razy (tzn. Nie jest to strumień), powinieneś najpierw użyć,
tail(1)
aby uzyskać potrzebne dane z ostatniego wiersza i przekazać je do awk do sekwencyjnego przetwarzania pliku.tail
będzie szukał końca pliku, aby odczytać ostatni wiersz bez konieczności odczytu wszystkich danych przed nim.Będzie to duża wygrana dla dużych plików, w których cały plik nie zmieści się w buforze bufora (co oznacza, że trzeba będzie go odczytać z dysku dwa razy, raz dla każdego przejścia), i pomoże w mniejszym stopniu, nie wymagając skanowania wejście, aby przejść do ostatniego wiersza. Mniejsze pliki mogą nie wykazywać dużej różnicy w podejściu dwuprzebiegowym.
źródło
Możesz załadować je do tablicy i odczytać do tyłu:
Możesz to zrobić bardziej wydajnie, ale ten rodzaj ilustruje, dlaczego
awk
nie jest do tego odpowiednie narzędzie. Kontynuuj używanie,tac
tam gdzie jest to możliwe, GNU tac jest zazwyczaj najszybszym z wielu narzędzi do tego zadania.źródło
for
-loops wawk
nie jest rozwiązaniem.