Depois de criar um diretório de teste contendo os seguintes arquivos:
Image_104_Data_9878_n0.txt, Image_104_Data_9878_n1.txt,
Image_234_Data_7778_n0.txt, Image_234_Data_7778_n1.txt,
Image_234_Data_7778_n2.txt, Image_954_Data_4478_n0.txt,
Image_954_Data_4478_n1.txt, Image_954_Data_4478_n2.txt
Eu então fiz:
printf %s\n * | sort --debug -t_ -k2,2n -k5.2n,5.2n
E os resultados foram:
Image_104_Data_9878_n0.txt
___
_
__________________________
Image_104_Data_9878_n1.txt
___
_
__________________________
Image_234_Data_7778_n0.txt
___
_
__________________________
Image_234_Data_7778_n1.txt
___
_
__________________________
Image_234_Data_7778_n2.txt
___
_
__________________________
Image_954_Data_4478_n0.txt
___
_
__________________________
Image_954_Data_4478_n1.txt
___
_
__________________________
Image_954_Data_4478_n2.txt
___
_
__________________________
Eu disse sort
para classificar primeiramente por número no campo delimitado por 2cd _
do início do campo ao final do campo como -k2,2n
e secundariamente para classificar numericamente no segundo byte de 2cd no quinto campo como -k5.2,5.2n
. Eu pedi por --debug
de saída para me mostrar o que diabos estava fazendo.
Eu poderia ter classificado principalmente no 4º campo com facilidade, ou principalmente no campo 2, secundariamente no campo 5.2 e menos importante no segundo campo. Digo tudo isso porque não consigo determinar qualquer rima ou razão para o tipo oferecido em seu exemplo e só posso assumir que você os designou como:
- 1_1: 234/7778
- 2_1: 954/4478
- 3_1: 104/9878
... porque você, até agora, não tem nenhum comando adequado para resolvê-los e talvez precise de um pequeno conselho sobre como fazê-lo. Seguindo essa suposição, farei o seguinte:
printf %s\n * |
sort -t_ -k4,4n -k5.2n,5.2n |
nl -bp'_n0\.' -s_ |
sed 's/\(I[^.]*_n\)\(.*\)/:/;N
s/ *\([0-9]*_\)\(.*\n\) *\([^_]*I\)//;P;D'
Isso produz resultados que acredito que devem ser bem próximos do que você está procurando. Vêem?
1_0.txt:Image_954_Data_4478_n0.txt
1_1.txt:Image_954_Data_4478_n1.txt
1_2.txt:Image_954_Data_4478_n2.txt
2_0.txt:Image_234_Data_7778_n0.txt
2_1.txt:Image_234_Data_7778_n1.txt
2_2.txt:Image_234_Data_7778_n2.txt
3_0.txt:Image_104_Data_9878_n0.txt
3_1.txt:Image_104_Data_9878_n1.txt
Lá eles são classificados e numerados pelo quarto campo porque eu especifiquei o campo -k4,4n
para sort
, mas você poderia facilmente fazer o -k2,2n
como indicado.
O comando funciona pedindo nl
para numerar apenas as linhas que contêm a string _n0.
. sed
recebe sua saída, que se parece com:
1_Image_954_Data_4478_n0.txt
Image_954_Data_4478_n1.txt
Image_954_Data_4478_n2.txt
2_Image_234_Data_7778_n0.txt
Image_234_Data_7778_n1.txt
Image_234_Data_7778_n2.txt
3_Image_104_Data_9878_n0.txt
Image_104_Data_9878_n1.txt
... e primeiro copia o _n[0-9]*.txt
bit para o início da linha, N
ext puxa a próxima linha e, se o espaço padrão for semelhante:
*num_.*\n [^_]*I
... nesse ponto, ele liga o numero da primeira linha ao segundo. Se você quisesse ir do arquivo de texto que o comando produziria para uma operação de movimentação, você poderia fazer:
sed 's/\([^:]*\):\(.*\)/$* /' <txtfile |
sh -s -- echo mv
OUTPUT
mv Image_954_Data_4478_n0.txt 1_0.txt
mv Image_954_Data_4478_n1.txt 1_1.txt
mv Image_954_Data_4478_n2.txt 1_2.txt
mv Image_234_Data_7778_n0.txt 2_0.txt
mv Image_234_Data_7778_n1.txt 2_1.txt
mv Image_234_Data_7778_n2.txt 2_2.txt
mv Image_104_Data_9878_n0.txt 3_0.txt
mv Image_104_Data_9878_n1.txt 3_1.txt
Existe apenas echo
ed porque esse é o primeiro parâmetro do processo do shell, mas se você removê-lo e executá-lo, como acabei de fazer, você vai gostar de obter os mesmos resultados:
ls -m
1_0.txt, 1_1.txt, 1_2.txt, 2_0.txt, 2_1.txt, 2_2.txt, 3_0.txt, 3_1.txt
Gilles recomenda links, o que eu também acho que é uma excelente ideia, embora eu pessoalmente evite softlinks se eu puder ajudar e apenas fazer um diretório de hardlink espelhado. Você poderia fazer isso quase da mesma maneira, mas você usaria ln
em vez de mv
.