4行行を含むファイルがあります。以下は8行の内容を抜粋したものです。
6115 8.88443
6116 6.61875
6118 16.5949
6117 19.4129
6116 6.619
6117 16.5979
6118 19.4111
6115 8.88433
私がやりたいことは、最初の列に基づいて各ブロックが4つの行で構成されるブロックをソートすることです。抜粋の出力は次のようになります。
6115 8.88443
6116 6.61875
6117 19.4129
6118 16.5949
6115 8.88433
6116 6.619
6117 16.5979
6118 19.4111
答え1
1つのオプションは、次を使用することです。アッN行ごとに最初のシーケンス番号プレフィックスを追加します(あなたの場合はN = 4)。次に、デフォルトのソート列としてプレフィックスを入力しますsort
。
N = 4の例:
awk '{print int((NR-1)/4), $0}' file.txt | sort -n -k1,1 -k2,2 | cut -f2- -d' '
答え2
これがワンタイムであり、Python、Perl、またはawkを学びたくない場合は、基本とsplit
コマンドsort
を学ぶことができます。
まず、次のオプションを使用してファイルを4行のチャンクに分割します-l
。
split -a 6 -l 4 input_file my_prefix_
for fn in my_prefix_*; do
sort -n -o $fn $fn
done
cat my_prefix_* > output_file
rm my_prefix_*
sort -n
最初の列の値(1234より前の999)に基づいてソートします。-a 6
26^6*4 行のファイルを処理する必要があります。my_prefix_
使用しているディレクトリに固有のものでなければなりません。
答え3
Perlを使用してこれを行うことができます。
perl -nle '
push @a,$_;
unless($. % 4){
print join "\n",sort {$a <=> $b} @a; # Sort @a, and print its contents
@a = (); # Empty @a to start a new block
}
' your_file
どのように動作しますか?
-n
-->各入力行に対してコードを実行します(そして現在の行をに入れます$_
)。-l
-->すべての出力に改行を追加します。print
-e
-->次の文字列をPerlコードとして実行する- 各行は配列に追加されます
@a
。 $.
現在の行番号を保存します。行番号が0モジュールとして4に等しくない場合は、作業を続けます。その場合はい0モジュロ4と一致すると、数字が4の倍数(ブロックの終わり)である行に到達します。この場合、@a
項目を昇順に並べ替え、改行文字で連結された整列配列の項目を標準に印刷します。出力。
答え4
以下は「純粋な」awk
ソリューションです。
例データに示すように、インデックスが常に同じインクリメント順序(6115-6119)である場合は、アルゴリズム「ショートカット」を使用できます。
awk '{a[$1]=$0} !(NR%4){for(i=6115;i<6119;print a[i++]);}'
これは実際に
a
インデックス位置6115-6119に分散された配列にすべての行を追加します。- 4行()ごとに配列の
!(NR%4)
内容を繰り返し、目的の順序で印刷します。
数値インデックスが常に同じ4つのインデックスですが、増加する整数シーケンスがない場合は、次のようにソートする必要があります。
awk '{a[$1]=$0} !(NR%4){asort(a,b); for(i=1;i<5;print b[i++]);}'
注:これはGNU awk用であるため、他のユーザーはそれをサポートしていない可能性がありますasort
。
4つのブロックがそれぞれ異なる数値IDを持つことができる場合:
awk '{a[$1]=$0} !(NR%4){asort(a); for(i=1;i<5;print a[i++]); delete a}'
注:TILは以下に由来します。@Gilles自己回答(+2)この使い方はdelete
まだPOSIXではありませんが、一般的にサポートされています。。
使用する正しい™バージョンdelete
:
awk '{a[$1]=$0} !(NR%4){asort(a); for(i=1;i<5;delete a[i++]){print a[i]}}'
より多くのメモリとサイズを使用して削除されなかったバージョン:
awk '{a[n][$1]=$0} !(NR%4){asort(a[n]); for(i=1;i<5;print a[n][i++]); n++}