
Quero juntar alguns arquivos png em um pdf. O comando
convert *png out.pdf
funciona, mas erra a ordem. Acontece que
ls -v *png
dá a ordem que desejo, portanto quero passar sua saída para conversão.
eu tentei
convert `ls -v *png` out.pdf
mas isso não funciona porque os nomes dos arquivos contêm espaços e parênteses.
Dizendo ls
para definir os nomes dos arquivos entre aspas duplas via
convert `ls -vQ *png` out.pdf
também não funciona, pois as aspas parecem ser removidas na substituição.
O que posso fazer?
Responder1
Se você tiver um sistema recente baseado em GNU (que sort
fornece uma classificação de versão natural semelhante -V
), poderá classificar usando-o e ler o resultado em uma matriz:
while read -rd '' f; do
files+=("$f")
done < <(find . -maxdepth 1 -name '*png' -print0 | sort -zV)
Então você poderá expandir o array dentro do seu convert
comando:
convert "${files[@]}" out.pdf
Responder2
Se os nomes dos seus arquivos não tiverem novas linhas, você poderá fazer isso apenas dizendo ao shell para dividir a saída ls
apenas em novas linhas, e não em qualquer espaço em branco como padrão. Odivisãoé controlado pela IFS
variável, quaisquer caracteres contidos em IFS
são usados como delimitadores.
IFS=$'\n' # set it to just a newline
convert $(ls -vd ./*.png) output.pdf
Isso ainda pode ter problemas se os nomes dos arquivos forem engraçados o suficiente ou se ls
os confundirem para exibição. Ao imprimir em um terminal, ls
geralmente lista os arquivos em várias colunas. Mas quando a saída não vai para um terminal (o shell lê aqui), ela age como se -1
tivesse sido fornecida.
Para trabalhar com a ideia com a qual você começou, vocêpoderiausar eval
.
eval: eval [arg ...]
Combine ARGs em uma única string, use o resultado como entrada para o shell e execute os comandos resultantes.
Mas o problema eval
é que tudo e qualquer coisa na linha de comando é analisada novamente, e mesmo coisas que geralmente são seguras, não são. Pense em um arquivo chamado $(touch HELLO)
e no que acontece se um nome como esse for colocado na linha de comando.
Além disso, se você seguir esse caminho, convém usar --quoting-style=shell
em vez de, -Q
pois pode corresponder mais ao processamento dos caracteres especiais do shell. (Ambos podem ser específicos do GNU ls, mas acho que -v
também são.)
Responder3
Com zsh
, o (n)
qualificador glob fornece uma ordem de classificação semelhante à do GNU ls -v
:
convert ./*.png(n) out.pdf
Em um sistema GNU, com bash
, zsh
, yash
ou mksh
:ksh93
eval "files=($(ls --quoting-style=shell-always -vd ./*.png))"
convert "${files[@]}" out.pdf
Responder4
Usando GNU Parallel fica assim:
ls -vd ./*png | parallel -Xj1 convert {} out.pdf