カスタムパターンを使用したソート

カスタムパターンを使用したソート

カスタムモードでファイルの内容を出力する方法はありますか?

myfileたとえば、次の内容を含むファイルがあります。

a
d
b
c

..次のパターンを使用してソートする方法:最初に「b」で始まる行を印刷し、次に「d」で始まる行を印刷してから、通常のアルファベット順に行を印刷するので、予想される出力は次のようになります。

b
d
a
c

ベストアンサー1

データを容量を超えてソートする必要がある場合、sort一般的な方法はデータを前処理し、前にソートキーを追加してソートし、最後に重複ソートキーを削除することです。たとえば、ここで0行が始まる場合はbaを追加し、行が始まる1場合はdaを追加し、2そうでない場合はaを追加します。

sed -e 's/^b/0&/' -e t -e 's/^d/1&/' -e 't' -e 's/^/2/' |
sort |
sed 's/^.//'

これにより、すべてとb行がd並べ替えられます。行を元の順序で維持するには、最も簡単な方法は次のとおりです。ソートされていない行を分割します。。ただし、元の行をソートキーに変換できますが、nlここではより複雑です。 (\tsedがこの構文を理解していない場合は、タブ全体をリテラルタブに置き換えてください。)

nl -ba -nln |
sed 's/^[0-9]* *\t\([bd]\)/\1\t&/; t; s/^[0-9]* *\t/z\t0\t/' |
sort -k1,1 -k2,2n |
sed 's/^[^\t]*\t[^\t]*\t//'

または、カスタムソート機能を簡単に指定できるPerl、Python、Rubyなどの言語を使用してください。

perl -e 'print sort {($b =~ /^[bd]/) - ($a =~ /^[bd]/) ||
                     $a cmp $b} <>'
python -c 'import sys; sys.stdout.write(sorted(sys.stdin.readlines(), key=lambda s: (0 if s[0]=="b" else 1 if s[0]=="d" else 2), s))'

bまたは、合計行の元の順序を維持したい場合d

perl -e 'while (<>) {push @{/^b/ ? \@b : /^d/ ? \@d : \@other}, $_}
         print @b, @d, sort @other'
python -c 'import sys
b = []; d = []; other = []
for line in sys.stdin.readlines():
    if line[0]=="b": b += line
    elif line[0]=="d": d += line
    else: other += line
other.sort()
sys.stdout.writelines(b); sys.stdout.writelines(d); sys.stdout.writelines(other)'

おすすめ記事