1. 概要

テキストの行の並べ替えは、Linuxでは一般的なタスクです。 このチュートリアルでは、例を通してsortコマンドを学習します。

2. sortコマンドの概要

sort コマンドは、標準入力(stdin)またはテキストファイルから行を再配置するのに役立ちます。 sortコマンドは、ソートされた結果を標準出力(stdout)に書き込みます。 GNU coreutils パッケージの一部であるため、すべてのLinuxディストリビューションで使用できます。

sortコマンドを使用する構文は簡単です。

sort [OPTION]... [FILE]...

並べ替えユーティリティはデフォルトで行をアルファベット順に並べ替えます

$ cat cities.txt
New York City
Paris
Beijing
Hamburg
Los Angeles
Amsterdam

$ sort cities.txt
Amsterdam
Beijing
Hamburg
Los Angeles
New York City
Paris

ただし、さまざまなオプションを渡すと、 sort コマンドは、行を番号、逆順、フィールドなどで並べ替えるなど、それ以上のことを実行できます。

sort コマンドを使用してさまざまな方法で行を並べ替える方法を学ぶために、いくつかの例を見ていきます。

3. 番号で並べ替え

多くの場合、行を数値で並べ替える必要があります。 これを行うには、オプション-nsortに渡すことができます。

新しいファイルcities2.txt、を作成し、新しい列を追加しましょう:人口(百万単位)。 新しいファイルの行を人口で並べ替えます。

$ cat cities2.txt
8.18 New York City
2.15 Paris
21.45 Beijing
1.82 Hamburg
3.90 Los Angeles
1.38 Amsterdam

$ sort -n cities2.txt
1.38 Amsterdam
1.82 Hamburg
2.15 Paris
3.90 Los Angeles
8.18 New York City
21.45 Beijing

さて、行は上記の出力の人口によってソートされています。

sort -n は、10進数で行を並べ替えるのに役立ちます。 ただし、符号付きの2進数または16進数を正しく並べ替えることはできません。

4. 逆順に並べ替える

ファイルを逆の順序で並べ替えるには、オプション-rを使用します。

次に、ファイルcitys2.txtを人口の降順で並べ替えます。

$ sort -nr cities2.txt 
21.45 Beijing
8.18 New York City
3.90 Los Angeles
2.15 Paris
1.82 Hamburg
1.38 Amsterdam

5. 月で並べ替え

「11月」や「8月」など、テキストに月が含まれる場合があります。 sortコマンドは、月ごとに行をソートする便利な-Mオプションをサポートしています

$ cat months.txt 
October
January
December
November
August

$ sort -M months.txt
January
August
October
November
December

6. ASCII文字コードで並べ替え

時々、テキスト内のASCII文字コードで行をソートしたいと思います。

テキストファイルを見てみましょう:

$ cat ascii.txt
C
B
b
c
A
a

sort コマンドのデフォルトオプションを使用して並べ替えると、次のようになります。

$ sort ascii.txt
a
A
b
B
c
C

結果はアルファベット順にソートされます。

ただし、ASCIIコード順ではありません。 たとえば、大文字の「A」のASCIIコードは65ですが、小文字の「a」のASCIIコードは97です。

LC_ALL は、他のローカリゼーション設定をオーバーライドする環境変数です。 代わりにASCIIコードで行を並べ替えるには、環境変数LC_ALL = C、を設定して、並べ替えをバイト単位で強制する必要があります。

この環境変数がsortコマンドのデフォルトの動作をどのように変更するかを見てみましょう。

$ LC_ALL=C sort ascii.txt
A
B
C
a
b
c

上記のコマンドでは、sortコマンドの実行専用にLC_ALL=Cを一時的に設定しています。 現在のシェルのLC_ALL値は変更されません。

7. ソートされた出力をファイルに書き込む

デフォルトでは、sortコマンドは結果をstdoutに書き込みます。出力をファイルに保存したい場合があります。 -oFILEオプションをsortコマンドに渡して、結果をstdoutではなくファイルに書き込むことができます。

$ sort -o ascii_result.txt ascii.txt
$ cat ascii_result.txt
a
A
b
B
c
C

-o オプションを使用することに加えて、stdoutを出力ファイルにリダイレクトすることもできます。

$ sort ascii.txt > ascii_result.txt

ただし、ソートされた結果を入力ファイルに書き戻す場合は、一時ファイルを介して行う必要があります。

$ sort ascii.txt > sorted.tmp && mv sorted.tmp ascii.txt
$ cat ascii.txt
a
A
b
B
c
C

8. 重複の並べ替えと削除

-uオプションをsortコマンドに渡すと、「一意の」結果が生成され、ソートされた行が出力され、重複が削除されます。

$ cat dup.txt 
New York City
Paris
Beijing
Paris
New York City
Hamburg
New York City
Hamburg

$ sort -u dup.txt 
Beijing
Hamburg
New York City
Paris

9. キーで並べ替え

これまでは、常に行頭の項目でソートしてきました。 キーで行を並べ替えることもできます。 これを行うには、-kオプションをsortコマンドに渡します。 

CSVファイルなどのフィールドベースのデータを並べ替える必要がある場合に非常に便利です。

CSVファイルの稼働時間レポート(名前、月、稼働時間、コメント)で学習しましょう。

$ cat working_hours.csv
Dr.Schmidt,Jan,123,some comments...
Mr.Green,Feb,20,some comments...
Dr.Schmidt,Mar,25,some comments...
Mr.Adams,Jan,77,some comments...
Mr.Green,Jan,45,some comments...
Mr.Adams,Feb,150,some comments...
Mr.Adams,Mar,80,some comments...
Mr.Green,Mar,107,some comments...
Dr.Schmidt,Feb,87,some comments...

次に、CSVファイルをフィールドとフィールドの一部で並べ替える方法を説明します。

9.1. フィールドで並べ替え

たとえば、3番目のフィールド WorkingHoursで行を並べ替えたいとします。

最初に問題を解決するために、sortコマンドを見ていきます。

$ sort -t, -k 3n,3 working_hours.csv
Ms.Green,Feb,20,some comments...
Dr.Schmidt,Mar,25,some comments...
Ms.Green,Jan,45,some comments...
Mr.Adams,Jan,77,some comments...
Mr.Adams,Mar,80,some comments...
Dr.Schmidt,Feb,87,some comments...
Ms.Green,Mar,107,some comments...
Dr.Schmidt,Jan,123,some comments...
Mr.Adams,Feb,150,some comments...

それでは、コマンドの各部分を理解しましょう。

sortコマンドのデフォルトのフィールド区切り文字は空白です。 オプション-tを使用してカスタムフィールドセパレータを定義することもできます。 CSVファイルのフィールドはカンマで区切られているため、「 -t、」。

次に、 -kオプションの並べ替えキー3n、3を定義しました。 sortコマンドでのキーの定義は次のとおりです。

POS1[sorting options],POS2

POS1 は開始キー位置を示し、POS2は終了キー位置を示します。 私たちが与えない場合 POS2 、行の終わりは、 POS2。 

私たちの目標は、 -n (数値)オプションを使用して3番目のフィールドで並べ替えることです。したがって、 -k 3n、3。があります。

9.2. フィールドの一部で並べ替える

フィールドで並べ替えると、フィールドベースのデータを並べ替えるのに大いに役立ちます。 ただし、フィールドの一部を並べ替えキーにしたい場合があります。

次に、前のセクションの要件を拡張しましょう。最初にworking_hours.csvを人の名前で並べ替えてから、勤務時間で並べ替えます。

勤務時間による並べ替えは私たちにとって問題ではありませんが、人の名前で並べ替えることに気付いたので、タイトルを除外する必要があります( MS。 氏 博士 )最初のフィールドから。

最初にソリューションを見てから、フィールドの一部で並べ替える方法を理解しましょう。

$ sort -t, -k 1.4,1 -k 3n,3 working_hours.csv
Mr.Adams,Jan,77,some comments...
Mr.Adams,Mar,80,some comments...
Mr.Adams,Feb,150,some comments...
Ms.Green,Feb,20,some comments...
Ms.Green,Jan,45,some comments...
Ms.Green,Mar,107,some comments...
Dr.Schmidt,Mar,25,some comments...
Dr.Schmidt,Feb,87,some comments...
Dr.Schmidt,Jan,123,some comments...

ソートキー1.4,1でうまくいきました。 その意味を理解しましょう。

並べ替えキーがPOS1、POS2として定義されていることを学びました。 さらに、各POSFCとして定義されているため、完全なソートキーの定義は次のとおりです。

F1.C1[sorting options],F2.C2

F1およびF2は、フィールドインデックスを表します。 この場合、1番目のフィールドは1です。

C1 は、ソート比較を開始するためのフィールドF1内の文字インデックスです。 C1 を定義しない場合、比較はフィールドF1の最初の文字から始まります。

C2 は、ソート比較を終了するためのフィールドF2内の文字インデックスです。 C2 を省略すると、並べ替えの比較はフィールドF2の最後の文字で終了します。

この例では、 Name フィールドからタイトルを除外するために、並べ替えの比較は4番目の文字から開始する必要があります。 したがって、「-k1.4,1」があります。

10. TSVファイルを並べ替える

これまで、ファイルをフィールドで並べ替える方法を学び、CSV入力ファイルを例として使用してきました。

実際には、TSV(タブ区切り値)は、一般的に使用されるもう1つのデータ形式です。 このセクションでは、TSVファイルを並べ替えて、フィールドによる並べ替えの手法を確認しましょう。

いくつかの有名な映画俳優が重量挙げゲームのために集まって、試合結果( 名前、体重 、 スコア )はTSVファイルに記録されます:

$ cat match_result.tsv
Brad Pitt       78.50   150.00
Michael Caine   77.60   149.50
Tom Hanks       79.00   148.00
Cary Grant      78.80   149.50
Spike Lee       80.00   149.50
Vin Diesel      77.89   150.00
David Tennant   79.50   147.50
Jackie Chan     78.77   151.00
Will Smith      80.50   148.00

今、私たちのタスクは、試合のランクを計算することです。 重量挙げのルールによると:

  • 2人のプレーヤーのスコアは異なります。スコアの高いプレーヤーが勝ちます。
  • 2人のプレーヤーのスコアは同じです。体重が少ないプレーヤーが勝ちます。

したがって、最初に3番目のフィールドを降順で並べ替えてから、2番目のフィールドを昇順で並べ替える必要があります

この問題の難しい部分は2つのフィールドで並べ替えることですが、今のところ私たちにとっては難しいことではありません。 フィールドで並べ替えるコマンドを作成できます: sort -k3nr、3 -k2n、2match_result.tsv

-t オプションを使用して、フィールドセパレータとしてTabを指定する必要があります。

やるだけやってみよう:

$ sort -t'\t' -k3nr,3 -k2n,2 match_result.tsv
sort: multi-character tab ‘\\t’

おっと、sortは’\ t ‘を複数文字として扱います! 次に、Tabをフィールドセパレータとして正しく渡す方法を見てみましょう。

10.1. フィールドセパレータとしてタブを渡す

sortコマンドにフィールドセパレータとしてTabを渡す方法は2つあります。

  • リテラルタブを渡す
  • タブ文字のエスケープ

通常、コマンドラインに TAB キーを入力すると、コマンドにリテラルTabが表示される代わりに、コマンド補完がトリガーされます。

ただし、最初にCTRL-Vを入力し、次にTAB と入力することで、コマンドラインにリテラルタブを追加できます。

$ sort -t' ' -k3nr,3 -k2n,2 match_result.tsv
Jackie Chan     78.77   151.00
Vin Diesel      77.89   150.00
Brad Pitt       78.50   150.00
Michael Caine   77.6    149.50
Cary Grant      78.80   149.50
Spike Lee       80.00   149.50
Tom Hanks       79.00   148.00
Will Smith      80.50   148.00
David Tennant   79.50   147.50

上記のコマンドでは、 -t ‘

タブを-tオプションに渡す別の方法は、ANSI-C引用を使用してタブをエスケープすることです。

$ sort -t$'\t' -k3nr,3 -k2n,2 match_result.tsv
Jackie Chan     78.77   151.00
Vin Diesel      77.89   150.00
Brad Pitt       78.50   150.00
Michael Caine   77.60   149.50
Cary Grant      78.80   149.50
Spike Lee       80.00   149.50
Tom Hanks       79.00   148.00
Will Smith      80.50   148.00
David Tennant   79.50   147.50

すごい! 問題を解決しました。 ジャッキー・チェンが一等賞を獲得しました!

11. 結論

sort は、便利でわかりやすいコマンドラインユーティリティです。 この記事では、例によってsortコマンドの一般的な使用法をいくつか学びました。

-k オプションを使用したキーによる並べ替えは、他の並べ替えオプションほど簡単ではありません。 ただし、フィールドベースのデータをより柔軟に並べ替えることができます。

TSVファイルを並べ替えるときは、フィールド区切り文字としてTabを正しく渡す必要があることに注意してください。

コマンドラインアーセナルにあるこの便利なツールを使用すると、ほとんどの並べ替えの問題を簡単に解決できます。