DD-MM-YYYY日付でファイルをソートする方法

DD-MM-YYYY日付でファイルをソートする方法

以下を含むファイルから:

...
18-11-2018:othercharacters
10-11-2018:othercharacters
03-10-2018:othercharacters
30-10-2018:othercharacters
27-09-2018:othercharacters
03-12-2018:othercharacters
...

注文する:

sort -t- -k2 -k1 

日付で並べ替えられません。何を見逃していますか?

答え1

これが推奨される日付形式がYYYY-MM-DDである理由の1つです。

-k22番目のフィールドで始まる行の部分を並べ替えるには、2番目のフィールド-k2,2だけを並べ替えます。

sort -b -t- -k2,2 -k1,1

または:

sort -b -k1.7,1.10 -k1.4,1.5 -k1.1,1.2

まず、年ごとに並べ替え(最初のフィールドの7〜10番目の文字(フィールドの先行スペースを無視し、デフォルトのフィールド区切り-b文字を使用して計算されます(スペース以外の文字をスペースに変換))、月ごとに日を並べ替えます。 。

答え2

-k2withを使用すると、ユーティリティsortは2番目のフィールドから始まる行全体をソートキーとして使用します。このソートキーが一意でない場合、-k1後者は絶対に使用されません。 2番目のフィールドのみを最初のソートキーとして使用するには、を使用します-k2,2。他のソートキーが一意でない場合(そして「フル行」が最初のフィールドで始まる場合)、デフォルトでは行全体がソートキーとして使用されるため、-k1追加する必要はありません。-k1,1sort

つまり、次の3つのコマンドは同じです。

sort -t - -k 2,2 -k 1,1 file
sort -t - -k 2,2 -k 1 file
sort -t - -k 2,2 file

以下はより一般的なソリューションです。

データがフィールド区切り文字として使用される「単純な」ヘッダーなしのCSVファイルに解析できると仮定すると、最初のフィールドの:日付を新しいフィールドのUnixタイムスタンプに変換し、その新しいフィールドに基づいてソートしてからそのフィールドを削除します。できます。これは時々呼び出されます。シュワルツ変換

使用ミラー:

$ mlr --csvlite --fs : -N put '$key = strptime($1,"%d-%m-%Y")' then sort -f key then cut -x -f key file
27-09-2018:othercharacters
03-10-2018:othercharacters
30-10-2018:othercharacters
10-11-2018:othercharacters
18-11-2018:othercharacters
03-12-2018:othercharacters

このput式は名前付きフィールドを生成し、key呼び出しの結果とともに呼び出されますstrptime()。これは(「2018-11-18」)と同様のUnixタイムスタンプであり、1542499200.0000001970-01-01が開始されてからの秒数を表します。次に、sortフィールドの操作を使用してとして削除しますcut -x

答え3

より一般的な年/月/日ソートソリューションでは、最初の:コロン()をコロン+ダッシュ(-:)に置き換え、フィールド3、2、1にソートしてから、コロン+ダッシュをコロンに置き換えて完了できます。 (これにより、年が行の残りの部分とは別のフィールドに分割され、行とは無関係に並べ替えることができます。これは、-:データの最初の3つのフィールドでは発生しないと仮定します。)

sed 's/:/-:/' file | sort -t'-' -k3,3 -k2,2 -k1,1 | sed 's/-:/:/'

私たちに示したデータセットで年を並べ替える必要がないようです。

関連情報