2012-08-13 7 views
10

Mam plik z długiej listy liczb całkowitych:Shell skrypt: znaleźć maksymalną wartość w sekwencji liczb całkowitych bez sortowania

10 
4 
66 
.... 

Chcę znaleźć maksymalną wartość przy użyciu narzędzi wiersza polecenia UNIX. Wiem, że mogę użyć sort (i rzeczywiście są rozwiązania tego problemu na SO, które używają sort), ale to nieefektywne, wymagające O (N * log (N)) i mnóstwo pamięci. Z prostą pętlą for, powinienem być w stanie znaleźć maksymalną wartość w O (N) i parę bajtów pamięci.

Wygląda na to, że musi istnieć jakiś program (o nazwie takiej jak max), który robi to po wyjęciu z pudełka --- czy to prawda?

Odpowiedz

24

Spróbuj tego:

awk '$0>x{x=$0};END{print x}' input.txt 

[AKTUALIZACJA:]

awk 'BEGIN{x=-2147483648};$0>x{x=$0};END{print x}' input.txt 

Inicjowanie x umożliwia rozwiązanie prawidłowo obsługiwać list całkowitą o wartości < = 0. Zobacz komentarze więcej szczegółów.

+0

Dobra! Zauważ, że ';' zanim 'END' nie jest potrzebny. – fedorqui

+0

Jedno miejsce, w którym to się nie powiedzie. Jeśli lista liczb całkowitych ma tylko jedną wartość, a ta wartość to 0. Twoje dane wyjściowe są puste. Tak właściwie. Jeśli masz jedną listę wartości o wartości <= 0, jest ona pusta. Negatywy nie będą działać, albo się pojawią. Właściwie ... negatywy w ogóle nie działają z tym (pojedyncza wartość lub nie). – stuckj

+0

Po dalszych badaniach nie powiedzie się, jeśli jedynymi wartościami na liście są <= 0, ponieważ nie zainicjowano x. Możesz rozwiązać ten problem, używając 'awk 'BEGIN {x = <>}; 0 0> x {x = 0 0}; END {print x}'' gdzie <> jest naprawdę liczbą ujemną. Np .: 'awk 'BEGIN {x = -2147483648}; 0 0> x {x = 0 0}; END {print x}'' przy założeniu wersji awk skompilowanej z 32-bitowymi wartościami dla zmiennych. – stuckj

0
max=1 

while read i 
do 
    if [[ "$i" > "$max" ]]; then 
    max="$i" 
    fi 
done < a.txt 

echo "$max" > b.txt 

a.txt jest plikiem wejściowym (z liczbą całkowitą w każdym wierszu). b.txt zawiera maksymalną liczbę całkowitą w pliku a.txt.

+0

'' 'i' <'służą do sortowania leksykalnego w trakcie testów. Użyj '(())' lub 'let' w powłokach, które je obsługują, lub' [n-gt m] 'dla skryptów POSIX. Ponadto zawsze używaj 'read -r'. Ponadto prawdopodobnie miałeś na myśli 'max = $ i'. – ormaaj

1
awk '{if($1>a)a=$1;}END{print a}' temp3 
-1

sort -nr plik_wejściowy.txt | head -1 gdzie plik inputfile.txt zawiera wszystkie liczby.

+2

źle. Pytanie brzmiało: _ "bez sortowania" _. – benka

Powiązane problemy