2016-12-17 9 views
0

GNUと元のソート順に維持したまま:どのようにランダムに並べ替えつのキー他は次のように入力リストを考えると、「並べ替え」

405:[email protected] 
405:[email protected] 
405:[email protected] 
405:[email protected] 
405:[email protected] 
405:[email protected] 
004:[email protected] 
004:[email protected] 
004:[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
005:[email protected] 
005:[email protected] 
005:[email protected] 

(あなたが見ることができるように、最初のフィールドがランダムでしたソートされています(元の入力は最初のフィールドがすべて数字順であり、最初は004、次に005,101,405など)。

最初のフィールド(コロン ':'で区切られている)が無作為にソートされ、ランダムソート中に2番目のフィールドのすべてのエントリが問題にならない無作為ソートが望ましいので、最初のフィールドが同じであるすべての行が一緒にグループ化され、ファイル全体にランダムに分散されるので、2番目のフィールドもランダムにソートされます。つまり、最終出力では、最初のフィールドで同じ値の行がグループ化されます(ただし、ファイル全体にランダムに分散されます)が、2番目のフィールドはランダムにソートされます。ソートキーなどに慣れていないので、私はこの望みの結果を得ることができません。

所望の出力は、次のようになります。

405:[email protected] 
405:[email protected] 
405:[email protected] 
405:[email protected] 
405:[email protected] 
405:[email protected] 
004:[email protected] 
004:[email protected] 
004:[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
101:[email protected] 
005:[email protected] 
005:[email protected] 
005:[email protected] 

誰もが一種のこのタイプを達成するための方法を知っていますか?

ありがとうございました!

答えて

2

これはかなり簡単にawkで行うことができます。

awk -F: 'BEGIN{cmd="sort -R"} $1 != key {close(cmd)} {key=$1; print | cmd}' input.txt 

あるいは、簡単に説明するためにばらばら:ワンライナーとして

  • -F: - セットのawkのフィールドセパレータ結腸へ。
  • BEGIN{cmd="sort -R"} - 開始する前に、「ランダムソート」を実行するコマンドである変数を設定します。これは私のためにFreeBSDで動作します。 GNUソートでも動作するはずです。
  • $1 != key {close(cmd)} - 現在の行が処理された最後のものとは異なる最初のフィールドを持っている場合は、出力パイプを閉じ...
  • {key=$1; print | cmd} - そして最後に、「キー」VARを設定し、現在の行を印刷し、配管出力変数cmdに格納されたコマンドを使用します。

この使用法は、awk awesomenessの少しを利用しています。文字列(変数に格納されているかどうか)をパイプすると、そのパイプは使用時に自動的に作成されます。いつでも閉じることができ、その後の使用で新しいコマンドが再開されます。

この影響は、close(cmd)のたびに、現在ののランダムにソートされた行が印刷されることです。ファイルの最後に来ると、awkは自動的にcmdを閉じます。

もちろん、この解決策を実行するには、最初のフィールドを共有しているすべての行をグループ化することが重要です。

+0

を負いません。この代替としてエレガントが、別の方法ではありません。そのことを「awk」ワンライナーで見ることはすばらしいことです。私はPHPで同じことを実装しましたが、配列トラバーサルとシャッフルを含む約30行のコード(ファイルの読み込み、構文チェックなど)で実装しました。確かにはるかに高速で効率的です。 – Brendan

+0

私のオリジナルの質問によれば、GNU 'sort'の可能性があるかどうかは分かりますか?私はそうは思わないが、もしそれならばソート構文を見たいと思う。 – Brendan

+0

私は、GNUソートだけでは不可能だと確信しています。あなたの質問で説明した並べ替えは、ソートではなく、最初のフィールドでグループ化された単純なランダム化のように本当に簡単です。それになると、ここでランダム化するためにGNUソートしか使用していません。そのコマンドを他のものに置き換えることができます。各セクションの順序を逆転させる 'tac'やメールの本文として各グループをどこかに送る' mailx'があります。 – ghoti

1

$ awk -F: '!($1 in a){a[$1]=c++} {print a[$1] "\t" $0}' file | 
    sort -R -k2 | 
    sort -nk1,1 -s | 
    cut -f2- 

か、確かにそれをしたと、最初のグループ分け

$ sort -R file | 
    awk -F: '!($1 in a){a[$1]=c++} {print a[$1] "\t" $0}' | 
    sort -nk1,1 -s | 
    cut -f2- 
関連する問題