Nowe posty

xx Dystrybucja pod HP Omen (6)
Wczoraj o 23:30:08
xx [Poradnik] Wyszukiwanie Sterowników (2)
Wczoraj o 21:08:23
lamp Problem z Linux Lite po instalacji (0)
Wczoraj o 19:50:30
xx Ile pingwinów? (1)
Wczoraj o 08:59:24
xx konfiguracja pale moon (0)
2024-03-24, 21:53:42
xx Plasma 6 w Neonie ssie trochę mniej ... (10)
2024-03-23, 02:38:11
xx problem z instalacja sterowników do karty sieciowej (3)
2024-03-18, 18:10:16
xx Plik abc.001 (1)
2024-03-17, 17:48:27
xx Zlecę dopracowanie programu w MatLab (0)
2024-03-13, 15:28:40
xx Linux Mint 21.3 XFCE brak dźwieku po paru minutach (karta muzyczna zintegrowana) (5)
2024-03-12, 23:07:01

Autor Wątek: Min i Max w wierszu  (Przeczytany 2079 razy)

timus221

  • Gość
Min i Max w wierszu
« dnia: 2016-05-21, 21:42:46 »
W jaki sposób znalezc minimum i maximum w kazdym wierszu ? Próbowałem wiele komend lecz żadna się nie sprawdza

9111 1320
6548 76
1649 567 5700 4596 4586 6428
8625
2714 1241 6907 5996 8139 6357 9922

8134 9727 3553
3945 8573
1273
8719 1366 1076 8420 6859
1637 2327 6554 7458
1399 4370 9612 5217
6911 2235
504
2770 396
4149 151 6900 2107 1354
3550 3324 8695 8543 2258 7039
2630 4006
726 1256 7255
2214 1866 1935
5592 193 7491 2053 6353
5731 916 981 8463 5749
9557 8166

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3049
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
Odp: Min i Max w wierszu
« Odpowiedź #1 dnia: 2016-05-22, 10:32:19 »
Sezon zaliczeniowy w szczycie, dlatego nie podam kodu źródłowego.

Wystarczy jedna instrukcja, awk ze skryptem 8-linijkowym (żeby było czytelnie). Skrypt zapisany po polsku, ale że awk ma składnię c-watą, nie powinieneś mieć problemów z napisaniem go

1. Dla linii zawierających tylko spacje i cyfry {
2.   ustaw min i max na wartość pierwszego pola
3.   dla pól od 2 do ostatniego {
4.      jeżeli pole jest mniejsze niż min, to ustaw min na to pole
5.      jeżeli pole jest większe niż max, to ustaw max na to pole
6.   }
7.   Wypisz min, "...", max
8. }
Wynik dla twoich danych:
1320  ...  9111
76  ...  6548
567  ...  6428
8625  ...  8625
1241  ...  9922
3553  ...  9727
3945  ...  8573
1273  ...  1273
1076  ...  8719
1637  ...  7458
1399  ...  9612
2235  ...  6911
504  ...  504
396  ...  2770
151  ...  6900
2258  ...  8695
2630  ...  4006
726  ...  7255
1866  ...  2214
193  ...  7491
916  ...  8463
8166  ...  9557
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

timus221

  • Gość
Odp: Min i Max w wierszu
« Odpowiedź #2 dnia: 2016-05-22, 17:11:15 »
Zrobiłem tak  :
Dla minimum
awk '{min=$1; for (i=2; i<=NF; i++) if ($i < min) min=$i; print min}' numbers
dla maksimum
awk '{max=$1; for (i=2; i<=NF; i++) if ($i > max) max=$i; print max}' numbers

W sumie działa ale czy mógłbym prosić teraz o napisanie tego w lepszej formie ?
Z góry dziękuję

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3049
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
Odp: Min i Max w wierszu
« Odpowiedź #3 dnia: 2016-05-22, 20:20:14 »
Jest bardzo dobrze z trzema drobiazgami:

1. Obliczenia robi też dla linii bez liczb (to trzeba zrobić regexpem aktywacji bloku, w // przed pierwszym { - cała linia ma zawierać tylko znaki cyfr i spację w dowolnym układzie)
2. Możesz liczyć min i max równocześnie
3. Dla czytelności możesz skrypt AWKa zapisać w pliku, zrobić go wykonywalnym i w pierwszej linijce dać
#!/usr/bin/awk -f

/WymyślRegExpa/{
  min=max=$1
  for (i=2; i<=NF; i++){
    if ($i < min) min=$i
    if ($i > max) max=$i
  }
  print min "..." max
}
i używać jak aplikacji przez ./skrypt.awk dane.txt albo po prostu uruchamiać przez awk -f skrypt.awk dane.txt
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

timus221

  • Gość
Odp: Min i Max w wierszu
« Odpowiedź #4 dnia: 2016-05-22, 20:57:25 »
Dzieki wielkie,ten sposob działa,ale czym jest linia
#!/usr/bin/awk -f

Zazwyczaj jak pisałem skrypty to wpisywalem na poczatku
#!/bin/bash

Nie można by zapisac:


#!/bin/bash

awk '{
....}'

?

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3049
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
Odp: Min i Max w wierszu
« Odpowiedź #5 dnia: 2016-05-22, 21:42:54 »
Pierwsza linia skryptu zaczynająca się od #! to tzw "bangline". Działa to tak, że jak
a) skrypt ma atrybut wykonywalności i czytelności (atrybuty rx).
b) pierwsza linia skryptu skrypt brzmi #!/ścieżka/do/programu argBanglina

to wywołanie z linii poleceń
$> ./skrypt arg1 arg2
zamieniane jest na
/ścieżka/do/programu argBanglina ./skrypt arg1 arg2

Skrypty bash-a, które pokazałeś działają właśnie na tej zasadzie - kernel (bo ten manewr realizowany jest przez kernel) widząc skrypt basha uruchamia program bash z naszym skryptem jako argumentem.

Bangline działa dla każdego języka skryptowego, który znak # traktuje jako komentarz i skrypt do wykonania podawany jest jako parametr: bash, awk, sed, make, ruby, perl, python, elixir. Lista jest przedługa. Jest nawet "plugin" do języka Go, dający mu możliwość startu z banglina.

A co do pytania "czy można by napisać". Oczywiście tak, tylko że wtedy uruchamiasz bash-a tylko po to, żeby uruchomić z niego awk-a. To już lepiej od razu uruchamiać awka.
« Ostatnia zmiana: 2016-05-22, 21:48:58 wysłana przez Paweł Kraszewski »
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy