
入力する:
$ cat a.txt
1FOO2FOO3
4FOO5FOO5
2FOO1FOO9
$
出力:
$ cat a.txt | sort SOMEMAGIC
2FOO1FOO9
1FOO2FOO3
4FOO5FOO5
$
質問:複数の文字長の区切り文字がある場合は、どのように並べ替えますか? (「FOO」)?
例では、a.txt
2番目の列に基づいてソートします。
問題は、通常、数字はa.txt
何でもよいということです。
答え1
sed
たとえば、文字列を単一文字の区切り文字に置き換え、列で並べ替えてから区切り文字に置き換えるには、次のようにします。
sed -e s/FOO/X/g a.txt | sort -k 2,2 -t X | sed -e s/X/FOO/g
これは、入力に文字が表示されないことを知っていると仮定します。制御文字は一般的な候補ですが、入力形式の知識に基づいて選択する必要があります。
答え2
この試み:
$ perl -ane '
push @h,[$_,(split(/FOO/))[1]];
END {
print map { $_->[0] }
sort {$a->[1] <=> $b->[1]}
@h;
}
' file
2FOO1FOO9
1FOO2FOO3
4FOO5FOO5
説明する
各配列ref [line、key]を配列に保存します
@h
。[$_,(split(/FOO/))[1]]
ファイルの読み取りが終わったら:
@h
キーに基づいて配列の配列参照を並べ替えるsort {$a->[1] <=> $b->[1]}
- 元の行を抽出して
@h
印刷します。map { $_->[0] }
答え3
フィールドが数値であると仮定すると、sort
GNUバージョンの並べ替え役に立つかもしれません。のF
尾がフィールド2に入り、フィールド2がvalueを含むものとして扱われるように区切り文字をに設定します。フィールド 2 にバージョンソートを指定すると、数値ではなく接頭辞が無視され、出力がフィールド 2 の末尾の数値部分に基づいてソートされます。OO
FOO
sort
OO2, OO5 and OO1
OO
sort -k2,2V -t 'F' a.txt
2FOO1FOO9
1FOO2FOO3
4FOO5FOO5
または、awk
インメモリソリューションのオーバーヘッドを許可できる場合は、GNUを使用してください。
awk -F'FOO' '{a[$2]=$0};END{asort(a, b, "@ind_num_asc");
for (i in b) print b[i]}' a.txt
2FOO1FOO9
1FOO2FOO3
4FOO5FOO5
答え4
sort -k
区分線よりは目に集中しすぎればいいと思います。キーの文字範囲を指定できます。
info sort
...入力ライン「foo bar」が与えられたら、
sort
それを「foo」フィールドと「bar」フィールドに分割します。フィールド区切り文字は前または次のフィールドの一部とは見なされないため、「sort -t」「」を使用すると、同じ入力行に空のフィールド「foo」と「bar」という3つのフィールドがあります。ただし、行の終わりまで(または「-k 2」など)まで拡張されたフィールド(例:「-k 2,3」)、 範囲エンドポイント間のフィールド区切り文字を保持します。。
Stephaneが述べたように、その逆も同様です。バイト範囲を持つフィールドの断片だけを並べ替えることも、複数のキーを持つ同じフィールドの複数の断片を並べ替えることもできます。したがって、あなたの場合は、異なる範囲で同じフィールドを複数回使用できます。願いより?
sort -k1.5n -k1.1n --debug <<\DATA
1FOO2FOO3
4FOO5FOO5
2FOO1FOO9
DATA
sort: using simple byte comparison
sort: leading blanks are significant in key 1; consider also specifying 'b'
sort: key 1 is numeric and spans multiple fields
sort: key 2 is numeric and spans multiple fields
2FOO1FOO9
_
_
_________
1FOO2FOO3
_
_
_________
4FOO5FOO5
_
_
_________
sort
これは、主キーがフィールド1の5番目のバイトから始まり、フィールド1の終わりまで拡張され、次にフィールド1の最初のバイトからフィールド1の終わりまでソートされるように指示します。上記のように、この--debug
オプションはソートしようとすると非常に便利です。sort
しかし、ここにはデバッグはありません。
sort -k1.5n -k1.1n <<\DATA
1FOO2FOO3
4FOO5FOO5
2FOO1FOO9
DATA
###OUTPUT###
2FOO1FOO9
1FOO2FOO3
4FOO5FOO5
それぞれに1文字だけを使用するには、sort
範囲を狭くする必要があります。上記の例では、-k1.5n
バイト5からフィールドの最後まで作業するのは、キー仕様が次のように機能するためです。
-k[begin field].[first byte in key],[end field].[last byte in key]
したがって、この場合、結果は同じですが、次のように開くときと同じバイトで各フィールド範囲を閉じることができます。
sort -k1.5,1.5n -k1.1,1.1n
したがって、sort
各キーは1バイトのみで構成されます。