Quando você precisa que os dados sejam classificados além da capacidade de sort
, uma abordagem comum é pré-processar os dados para preceder uma chave de classificação, classificar e, finalmente, remover a chave de classificação extra. Por exemplo, aqui, adicione um 0
se uma linha começar com b
, um 1
se uma linha começar com d
e um 2
caso contrário.
sed -e 's/^b/0&/' -e t -e 's/^d/1&/' -e 't' -e 's/^/2/' |
sort |
sed 's/^.//'
Observe que isso classifica todas as linhas b
e d
. Se você quiser essas linhas na ordem original, a abordagem mais fácil é dividir as linhas que você deseja deixar sem classificação . Você pode, no entanto, trabalhar a linha original em uma chave de classificação com nl
- mas aqui é mais complicado. (Substitua \t
por um caractere de tabulação literal se o seu texto não entender essa sintaxe).
nl -ba -nln |
sed 's/^[0-9]* *\t\([bd]\)/\t&/; t; s/^[0-9]* *\t/z\t0\t/' |
sort -k1,1 -k2,2n |
sed 's/^[^\t]*\t[^\t]*\t//'
Como alternativa, use uma linguagem como Perl, Python ou Ruby, que permite especificar facilmente uma função de classificação personalizada.
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))'
ou se você quiser deixar as linhas b
e d
na ordem original:
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)'