バージョン番号のリストがあります。たとえば、それらがファイルversions.txtにあるとしましょう
1.2.100.4
1.2.3.4
10.1.2.3
9.1.2.3
バージョン順に並べ替えたいのですが。つまり:
1.2.3.4
1.2.100.4
9.1.2.3
10.1.2.3
「k」パラメーターを使用してさまざまなソートコマンドを使用してみましたが、実際にそれを引き出すほど十分に理解していません。任意の助けいただければ幸いです。
-V
オプションが最も優れていますが、私のオプションにはそのオプションがなかったため、新しいソフトウェアや他のソフトウェアをインストールしないようにしたいと思いました。
これは最終的に私のために働いたコマンドです:
sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n test.txt
コメントから:
sort -t. -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr
v
接頭辞をスキップするには:sort -t. -k 1.2,1n -k 2,2n -k 3,3n -k 4,4n
BSDはデフォルトで-V
を提供しないため、Benのソリューションは可能な限り近くなります。便宜上、<label>-<version>.<ext>
などのファイルをソートできるバージョンをここに投稿します。
% ls bla-*.ime | sed -Ee 's/^(.*-)([0-9.]+)(\.ime)$/\2.-1 \1\2\3/' | sort -t. -n -k1,1 -k2,2 -k3,3 -k4,4 | cut -d\ -f2-
bla-1.ime
bla-1.0.ime
bla-1.0.0.ime
bla-1.1.ime
bla-1.1.29.ime
bla-1.2.3.ime
bla-1.2.29.ime
bla-1.2.30.ime
bla-1.3.ime
bla-1.3.0.ime
bla-1.3.1.ime
bla-1.3.10.ime
bla-1.3.20.ime
bla-1.7.ime
bla-1.11.29.ime
bla-2.3.2.ime
bla-11.2.2.ime
簡単な説明:
ls
を使用して、ソートするファイルをリストします。-1
を追加して、短いバージョン番号を最初に並べ替えます(.0
の前でも)。 -1
を0
と同等と見なす場合は、1.3
を1.3.0
に変更できます。リストには、該当するファイル名のバージョンでソートされたリストが含まれています。 label
部分の追加のソートは、読者への課題として残されています。
このコマンド:
echo "1.2.100.4,1.2.3.4,10.1.2.3,9.1.2.3" | tr ',' '\n' | sort -V
出力を提供します:
1.2.3.4
1.2.100.4
9.1.2.3
10.1.2.3
Perlの場合:
sub compare_version_numbers {
my ($l,$r) = @_;
my @lx = split("\\.",$l);
my @rx = split("\\.",$r);
my $minlen = (@lx < @rx) ? @lx : @rx;
for (my $i=0; $i < $minlen; $i++) {
# make numeric by multiplying with 1
my $l_number = ($lx[$i] * 1);
my $r_number = ($rx[$i] * 1);
# compare with spaceship operator
my $l_vs_r = ($l_number <=> $r_number);
# return if decision is clear!
if ($l_vs_r != 0) {
return $l_vs_r
}
# otherwise, next part in array of version numbers
}
# if we are here, we could not decide - shortest entry wins!
return @lx <=> @rx
}