No bash, como classificar strings com números?


37

Se eu tiver esses arquivos em um diretório

cwcch10.pdf
cwcch11.pdf
cwcch12.pdf
cwcch13.pdf
cwcch14.pdf
cwcch15.pdf
cwcch16.pdf
cwcch17.pdf
cwcch18.pdf
cwcch1.pdf
cwcch2.pdf
cwcch3.pdf
cwcch4.pdf
cwcch5.pdf
cwcch6.pdf
cwcch7.pdf
cwcch8.pdf
cwcch9.pdf

como posso listá-los no Bash para que eles estejam em ordem numérica crescente com base na parte numérica da string. Portanto, a ordem resultante é cwcch1.pdf, cwcch2.pdf, ..., cwcch9.pdf, cwcch10.pdfetc.

No final, estou tentando concatenar os PDFs pdftkcom algo como o seguinte

pdftk `ls *.pdf | sort -n` cat output output.pdf

mas isso não funciona, pois minha classificação está errada.


Obrigado por todas as ótimas respostas para isso. Como sempre no Unix, existem várias maneiras excelentes de esfolar esse gato.
ngm

Respostas:


7

Algo assim pode fazer o que você deseja, embora seja necessário uma abordagem um pouco diferente:

pdftk $(for n in {1..18}; do echo cwcch$n.pdf; done) cat output output.pdf

Ah, boa abordagem! Realmente faz o que eu o que, obrigado.
ngm


30

Para este exemplo em particular, você também pode fazer isso:

ls *.pdf | sort -k2 -th -n

Ou seja, classifique numericamente (-n) no segundo campo (-k2) usando 'h' como o separador de campos (-th).


Dividir e classificar em um campo - é uma ótima dica que, com certeza, será útil no futuro, obrigado.
ngm

6

Você pode usar a -vopção no GNU ls: tipo natural de (versão) números dentro do texto.

ls -1v cwcch*

Isso não funciona com o BSD ls(por exemplo, no OS X), onde a -vopção tem um significado diferente.


Esta é a solução mais simples, ela precisa de mais votos positivos!
davidparks21

2

Use a expansão do shell diretamente em uma linha de comando. A expansão deve ordená-los corretamente. Se eu entendo pdftka sintaxe da linha de comando corretamente, isso fará o que você deseja:

# shell expansion with square brackets
pdftk cwcch[1-9].pdf cwcch1[0-9].pdf cat output output.pdf

# shell expansion with curly braces
pdftk cwcch{{1..9},{10..18}}.pdf cat output output.pdf

Ou você pode tentar uma abordagem diferente. Quando preciso fazer algo assim, geralmente tento meus números formatados corretamente com antecedência. Se eu chegar atrasado e os PDFs já estiverem numerados como o seu exemplo, usarei isso para renumerar:

# rename is rename.pl aka prename -- perl rename script
# this adds a leading zero to single-digit numbers
rename 's/(\d)/0$1/' cwcch[1-9].pdf

Agora a lsclassificação padrão funcionará corretamente.


2
Talvez um pouco mais sucintamente:pdftk cwcch{{1..9},{10..18}}.pdf ...
Pausado até novo aviso.

boa dica, acrescentou. É uma sintaxe de expansão de shell Bourne padrão ou uma bashextensão?
quack quixote

2

Aqui está um método apenas usando sort:

ls | sort -k1.6n

0

Classificar -g é usado para classificar números em ordem crescente.

anthony@mtt3:~$ sort --help | egrep "\-g"
-g, --general-numeric-sort  compare according to general numerical value


O liner a seguir itera sobre um arquivo com os nomes dos arquivos PDF e captura os números apenas com egrep -o e usa sort -g para classificar os números em ordem crescente . Em seguida, ele alimenta esses números para sed e os conecta. Em seguida, libera a saída de duplicatas com uniq.


No lugar do uniq, você também pode usar o awk:

awk '!x[$0]++'

O acima é equivalente a uniq.


O que você está procurando é este liner:

for i in `cat tmp | egrep -o "[0-9]*" | sort -g`; do cat tmp | sed "s/\(^[a-z]*\)\([0-9]*\)\(\.pdf\)/\1$i\3/g" | uniq; done


Conteúdo do tmp:

anthony@mtt3:~$ cat tmp
cwcch10.pdf
cwcch11.pdf
cwcch12.pdf
cwcch13.pdf
cwcch14.pdf
cwcch15.pdf
cwcch16.pdf
cwcch17.pdf
cwcch18.pdf
cwcch1.pdf
cwcch2.pdf
cwcch3.pdf
cwcch4.pdf
cwcch5.pdf
cwcch6.pdf
cwcch7.pdf
cwcch8.pdf
cwcch9.pdf 

EDITAR:

Saída do comando:

anthony@mtt3:~$ for i in `cat tmp | egrep -o "[0-9]*" | sort -g`; do cat tmp | sed "s/\(^[a-z]*\)\([0-9]*\)\(\.pdf\)/\1$i\3/g" | uniq; done

cwcch1.pdf
cwcch2.pdf
cwcch3.pdf
cwcch4.pdf
cwcch5.pdf
cwcch6.pdf
cwcch7.pdf
cwcch8.pdf
cwcch9.pdf
cwcch10.pdf
cwcch11.pdf
cwcch12.pdf
cwcch13.pdf
cwcch14.pdf
cwcch15.pdf
cwcch16.pdf
cwcch17.pdf
cwcch18.pdf

Será que este trabalho um forro sobre o tmparquivo? Alguma saída para colar na resposta?
Xen2050 30/11/2015

Sim. Incluí a saída no meu OP na seção de edição.
Aguevara 30/11/2015
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.