次のように、いくつかの数値を含むファイルがあります。
21 12 33 35 21 12 33 44 52 63 14 12 23 34 11 12 13 53 1 12 43 33 44
これらの値の最大値、63
を見つけるにはどうすればよいですか? stats
を使用したかったのですが、このコマンドが私のマシンに存在しないようで、インストールしたくありません。 Perl
を使用してどのようにアプローチできますか?
List::Util
(5.8以降の標準ライブラリの一部。それ以外の場合はCPANで利用可能):
Perl -MList::Util=max -lane 'print max(@F)'
他の答えはかなりいいです、そして、Perl/awkは行く方法です。
楽しみのために、これを使用することもできます(GNU grep
と仮定):
$ grep -Eo '[0-9]+' file | sort -rn | head -n 1
63
grep -Eo '[0-9]+' file
は、正の10進整数のすべての一致をファイルに出力します。 -o
フラグに従って、各一致は別の行に出力されます。sort -rn
は、リストを数値順に逆にソートするため、最初の数値が最大になります。head -n 1
は最初の行を出力します。ステップごと:
$ grep -Eo '[0-9]+' file
21
12
33
35
21
12
33
44
52
63
14
12
23
34
11
12
13
53
1
12
43
33
44
$ grep -Eo '[0-9]+' file | sort -rn
63
53
52
44
44
43
35
34
33
33
33
23
21
21
14
13
12
12
12
12
12
11
1
私はこれがPerlではないことを知っています:
awk '{for(i=1;i<=NF;i++) if($i>maxval) maxval=$i;}; END { print maxval;}' file
別のPerl
ソリューション:
$ Perl -MList::Util=max -anle 'print max(@F)' file
63
これは、ファイルに1行が含まれている場合に機能します。ファイルに複数の行があり、すべての行の最大値を検索する場合は、次のことを試してください。
$ Perl -MList::Util=max -alne '$tmp = max @F; $max = $tmp if $max < $tmp; END { print $max }'
これはUbuntuでは機能しますが、MacOSでは機能しませんでした。
echo "21 12 33 35 21 12 33 44 52 63 14 12 23 34 11 12 13 53 1 12 43 33 44" | grep -oE "[0-9]*" | sort -nr | head -n 1
数値に一致するパターンの最初のgrep(小数がある場合は。を追加)、次に数値を逆の順序で並べ替えてから、最初の結果を選択します。
次に、ソートを必要としない、より高速なPerlのアプローチを示します。
$ echo '21 12 33 35 21 12 33 44 52 63 14 12 23 34 11 12 13 53 1 12 43 33 44' |
Perl -lane 'map{$m=$_ if $_>$m}@F; print $m'
または、@ Gnoucがコメントで示唆したように:
$ echo '21 12 33 35 21 12 33 44 52 63 14 12 23 34 11 12 13 53 1 12 43 33 44' |
Perl -lane '$m<$_ and $m=$_ for @F; print $m'
正の10進整数だけでなく、さまざまな種類の数値(-2、1E-20、inf、0x2f、0b0101、0777 ...)をサポートしたい場合は、次のようにすることができます。
Perl -lne '
while (m{(?!<\w)(?:(0x[0-9a-f]+|
0b[01]+|
0[0-7]+)|
[-+]?(\d+(\.\d*)?|\.\d+)(e[-+]?\d+)?|
infinity|inf)(?!\w)}xgi) {
$v = defined($1) ? oct($1) : $&;
$m = $& unless defined($m) && $m >= $v
}
END {print $m if defined $m}'
Awk、grep、Perlは必要ありません。
{
for n in 21 12 33 35 21 12 33 44 52 63 14 12 23 34 11 12 13 53 1 12 43 33 44
do
echo $n
done
} | sort | tail -n1
はい、これはPerl
ではありませんが、GNU awk
が好きです
awk -v RS='[[:space:]]+' 'BEGIN{max=-inf};{max = $0>max? $0: max};END{print max}' file
63