.txtファイルを2列に並べ替えるには?

.txtファイルを2列に並べ替えるには?
Feb  7  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones

上記は、私がソートしたい項目の出力例です。最初の列では日付別に並べ替え、tjones右側ではユーザー別に並べ替えたいと思います。

tjonesデフォルトでは、すべてのインスタンスをまとめてグループ化しますが、日付で並べ替えたいと思います。これを行うためにどのコマンドを使用するのか、列を並べ替えるためにawkコマンドを使用する必要があるのか​​わかりません。

明らかにusersよりも多いので、tjonesこれら2つの列に基づいてソートしたいと思います。

次の試みましたが、「並べ替え:複数文字タブ '\ t'」エラーが発生します。

sort -t '\t' -k1,1 -k5,5n auth_2014uniq.txt > auth_2014uniqtest

答え1

sort特定のフィールドでソートを許可する-kオプション:

sort -k11 -k1,2 data

まず、フィールド11(ユーザー名)でソートし、次にフィールド1と2を一緒に(日付)でソートします。気づく順序が重要ですここでは、-k最初の最初のオプションで並べ替えてから、次のオプションを使用してタイを切ります(等)。

これは正確な出力に大きく依存します。空白の各シーケンスはフィールド区切り文字であるため、「検索失敗」は3つの異なるフィールドです。

実際のデータにタブ区切りのフィールドがあるように見えるように編集します。ただし、この場合、タブがどこにあるかはわかりません。そうで-tあれば、 - の引数としてリテラルタブを提供する必要があり、sortエスケープが理解されず、シェル\tも拡張されません。その中にリテラルタブを書くか、Ctrl-VTabタブに置き換えてください。それは"$(echo -ne '\t')"オプションです。この場合、対応するフィールド番号を変更してください。

-k5,5nフィールド 5 だけを数字で並べ替えます。データが数字ではないので、間違いのようです。


GNUsortおよびその他の一部には以下が含まれます。-M月を順番に並べ替えるために使用できる並べ替え拡張子。あなたはそれを使用することもできないかもしれません。FreeBSDそしてオペレーティングシステムしかし、その他 BSD商業用Unicesではなく。可能であれば、-k1,1M -k2,2n日付は正しい月/日順に並べ替えられます。ロケールによっても異なります。ログファイルと環境が異なるローカライゼーションを使用している場合は機能しません。これがない場合は、毎月グループ化され、毎月日付で正しくソートされます。

答え2

sed -n 's/\(.*user: \)\([^ ]*\)$/\2 \1\2/p' <<\DATA |\
sort -t' ' -k1,1 -k2,3M |\
sed 's/[^ ]* //'
Feb  7  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
Feb  8  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
Feb  5  domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones                                                        
Jan  7  domainserver dovecot[37495]: auth(default): od(chaz): lookup failed for user: chaz                                                            
Mar  7  domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones                                                        
DATA

出力

Jan  7  domainserver dovecot[37495]: auth(default): od(chaz): lookup failed for user: chaz
Feb  5  domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones
Mar  7  domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones
Feb  7  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
Feb  8  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones

まず、文字列を含む行のみを選択してデータを切り取ります。ユーザー:次に、次のフィールドを行の先頭にコピーします。したがって、次のデータが提供されます。

*CRUFT*user: nospaces$

ここで、$は行の終わりを表し、最初にすべきsedことは次のとおりです。

nospaces *CRUFT*user: nospaces$

...コピースペースなしキューの先頭に。これは通常、行のフィールド数の変更(1または2)が大きな影響を与えるため、この種の操作で一般的な慣行ですsortsort ただそれについて。とにかく、それがここで起こっていることです。

したがって、sed編集されたデータは、最初のフィールド(ユーザー名)|pipesort最初にソートしてから、2番目と3番目のフィールドをMONTH結合するeyに渡されます。-kその結果、すべての行はユーザー名でグループ化され、各グループは日付でソートされます。

最後にsortデータを引き渡してください後ろにsed他のフィールドを上書きし、|pipesedの最初のフィールドを削除します。そのフィールドは最初にそのフィールドにコピーされたために存在します。

関連情報