Se o objetivo final é colocar os arquivos no arquivo na ordem desejada, uma solução simples é criar um arquivo com os arquivos para classificar primeiro e depois adicionar os arquivos para classificar por último no arquivo existente. Isso pode ser generalizado para mais de dois segmentos de classificação. Isso requer a criação de um arquivo, você não pode acrescentar a um arquivo em um pipeline.
tar cf foo.tar /images/*collage.*
find /images ! -name '*collage.*' -print0 | sort -z | tar rf foo.tar --null -T -
Se você quiser executar uma classificação personalizada com apenas utilitários básicos, um método possível é adicionar um prefixo à linha que indica o grupo do qual o item faz parte. Organize para que as tags de prefixo sejam classificadas na ordem em que você deseja que os grupos sejam classificados e retire esses prefixos posteriormente.
find /images -print0 |
sed -z -e 's/.*collage\./1&/' -e 't' -e 's/^/2/' |
sort -z |
sed -z 's/^.//' |
tar …
Outra abordagem seria fazer a classificação em outro idioma, como Perl, Python ou Ruby, onde você pode expressar uma classificação personalizada. Se você fizer isso, poderá fazer a coleta de nomes de arquivos e até mesmo a produção do arquivo nesse idioma. Aqui está um exemplo de Perl que apenas faz a classificação:
perl -e '$,=$\="perl -e '$,=$\="perl -e '$,=$\="tar cf foo.tar /images/*collage.*
find /images ! -name '*collage.*' -print0 | sort -z | tar rf foo.tar --null -T -
"; print
map {substr($_,1)}
sort
map {$_ = (/collage\./ ? "1" : "2") . $_}
glob("/images/*")' /images/* | tar …
"; print
map {substr($_,1)}
sort
map {$_ = (/collage\./ ? "1" : "2") . $_}
@ARGV' /images/* | tar …
"; print sort {
$a =~ /collage\./ ? $b =~ /collage\./ ? $a cmp $b : 1 :
$b =~ /collage\./ ? -1 : $a cmp $b
} @ARGV' /images/* | tar …
E outro exemplo que faz a classificação por meio de uma reescrita temporária (é chamada de "transformação Schwarztian" na comunidade Perl):
find /images -print0 |
sed -z -e 's/.*collage\./1&/' -e 't' -e 's/^/2/' |
sort -z |
sed -z 's/^.//' |
tar …
Ambos os exemplos falharão se o comprimento combinado dos nomes dos arquivos exceder o limite de comprimento da linha de comando. Para evitar isso, deixe o Perl gerar os nomes dos arquivos.
perl -e '$,=$\="perl -e '$,=$\="perl -e '$,=$\="%pre%"; print
map {substr($_,1)}
sort
map {$_ = (/collage\./ ? "1" : "2") . $_}
glob("/images/*")' /images/* | tar …
"; print
map {substr($_,1)}
sort
map {$_ = (/collage\./ ? "1" : "2") . $_}
@ARGV' /images/* | tar …
"; print sort {
$a =~ /collage\./ ? $b =~ /collage\./ ? $a cmp $b : 1 :
$b =~ /collage\./ ? -1 : $a cmp $b
} @ARGV' /images/* | tar …
Se você precisar gerar nomes de arquivos recursivamente ou aplicar alguma filtragem, use Arquivo :: Localizar . Se você quiser gerar o arquivo em Perl, você pode usar o Archive :: Tar .