まとめ
sortの+POS1 -POS2 オプションと-k POS1,POS2 は同じでないから注意。
-kのPOS1は1足す必要あるけど、POS2は「通常」そのままだ。
簡単な例
$ cat sort2.txt
22 33 11
11 33 22
11 22 11
これを第2列でソートする。古いオプションだと以下。
$ sort +1 -2 test.txt
11 22 11
11 33 22
22 33 11
新しいオプションだと以下が正解。
sort -k 2,2 test.txt
11 22 11
11 33 22
22 33 11
つい、-k 2,3とやってしまうと結果が異なり悩む。
私がそこでハマりました。
$ sort -k 2,3 test.txt
11 22 11
22 33 11
11 33 22
はまりどころ
古いオプションは0オリジンだけど、新しい-kオプションでは1オリジン。
だから sort +1 -2をsort -k 2,3としてしまいそうになる。
例えば以下の記事を見ると先頭位置を0⇒1考慮したらOKと読める。
そう思ったら、嵌ります。
https://xtech.nikkei.com/it/article/COLUMN/20060227/230887/
pos2は+1しなくていいのはなぜ?
身も蓋もない言い方だけど仕様。
例えば以下。
https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html
On systems not conforming to POSIX 1003.1-2001, sort supports a traditional origin-zero syntax ‘+pos1 [-pos2]’ for specifying sort keys. The traditional command ‘sort +a.x -b.y’ is equivalent to ‘sort -k a+1.x+1,b’ if y is ‘0’ or absent, otherwise it is equivalent to ‘sort -k a+1.x+1,b+1.y’.
xとyは列の中での文字位置だけど通常は指定しないでしょうから、
-kだと「sort -k a+1.x+1,b」側になりますね。
aは+1だけど、bはそのまま。
追記
コメントで教えて頂いた、--debugオプション。これ知りませんでした。
ものすごく便利。
実は、+POS1 -POS2オプションから-k POS1,POS2オプションの書き換えで結果が異なり、かなり悩んだのですが、--debugで見れば瞬殺ですね。ありがとうございます!!
sort +1 -2 test.txt --debug
11 22 11
___
________
11 33 22
___
________
22 33 11
___
________
古いオプションだと2列目だけがキーだけど、
-k 2,3 だと2列目と3列目がキーになっているのがわかる。
sort -k 2,3 test.txt --debug
11 22 11
______
________
22 33 11
______
________
11 33 22
______
________
あと、
「sort: leading blanks are significant in key 1; consider also specifying 'b'」
とも言われるが、1行目の22の前の空白もキーに入っている点に注意。
さらに、sort -k 2,2 test.txtなどで横棒の線が
______
________
と2本あるけど、これは最初に2列目でソートするが33の部分は2レコード目と3レコード目が同じになるので、最後に全体をみて2レコード目と3レコード目の順序を決めるという意味。
この機能を「last-resort comparison」と言う(そうです)。
sortって古くからあるコマンドでなめていたけど、今回、ちょっと調べただけでも、キーの扱いとか列の区切り空白とかロケールとの影響とか、さまざまな事を知りました。本当に奥が深い。
さらに追記
いろいろと勉強になったページ
https://qiita.com/ko1nksm/items/af8f6305944a3920b925
日本語で+POS1 -POS2と-k POS1,POS2 の違いまで書かれているページ
https://kazmax.zpp.jp/cmd/s/sort.1.html