Como digitar vários nomes de arquivos com menos toques de tecla

16

Se eu quiser converter uma imagem pdf em png com imagemagick, eu faço algo como:

convert -trim -density 400 this_is_a_very_long_filename_of_my_pdf_file.pdf this_is_a_very_long_filename_of_my_pdf_file.png

O arquivo pdf geralmente tem um nome de arquivo muito longo por alguns motivos e eu quero que o arquivo png tenha o mesmo nome, exceto a extensão.

Normalmente eu seleciono this_is_a_very_long_filename_of_my_pdf_file.pdf duas vezes via tab e zsh-menu e altero então pdf para png manualmente para o segundo argumento.

No entanto, existe uma maneira mais rápida de fazer isso?

    
por student 06.07.2014 / 18:40

6 respostas

23

Você pode usar expansões de chaves :

convert -trim -density 400 this_is_a_very_long_filename_of_my_pdf_file.{pdf,png}
    
por 06.07.2014 / 18:44
5

Esta chamada para mogrify criará um novo arquivo png em vez de sobrescrever o pdf - esperamos;)

mogrify -trim density 400 -format png th*.pdf

para th * .pdf use o número apropriado de caracteres para selecionar o arquivo correto ou o melhor preenchimento da tabulação até que você tenha o nome completo.

Desta forma, você pode criar um alias para o comando inteiro, até o parâmetro png.

    
por 07.07.2014 / 01:03
5

Se você sempre usa o mesmo comando com pequenas variações (como o nome do arquivo), pode escrever uma função:

pdf2png() { convert -trim -density 400 "$1" "$1:r.png" }

(esta função é específica para zsh ), e para cada arquivo your_file.pdf você deseja converter:

pdf2png your_file.pdf

Nota 1: Você pode escrever o mesmo tipo de função para outros shells, mas isso é um pouco mais complexo.

Nota 2: Com zsh , as aspas são úteis apenas se a opção SH_WORD_SPLIT estiver definida (o que não é o padrão).

    
por 07.07.2014 / 09:19
4

Considere o uso de variáveis para armazenar seus nomes de arquivos. Eles também completam automaticamente:

f="this_is_a_very_long_filename_of_my_pdf_file"
convert -trim -density 400 "$f.pdf" "$f.png"

Eu uso aspas porque às vezes os espaços mordem.

Benefícios significativos disso são:

  1. Você pode realizar outras operações com o valor em $ f, sabendo que ele aponta para o arquivo correto
  2. É o mais curto dos saltos para colocar isso em uma estrutura cat listOfFiles | while read f; do ... ; done loop.
  3. Muitas vezes, nomes de arquivos gerados automaticamente são muito semelhantes, e o preenchimento automático fica muito irritante muito rapidamente se você tiver que fazer abc<tab>d<tab>x<tab>2<tab> etc. Dessa forma, você só precisa digitar uma vez, e você pode até mesmo pegar o arquivo mais recente ou o maior arquivo por meio de um script como f=\ ls -t | head -1 '', em vez de primeiro executar a pesquisa, procurando o nome do arquivo e transcrevê-lo como algum tipo de macaco treinado.
por 07.07.2014 / 11:27
2

Você também pode usar Expansão do histórico para se referir a palavras na linha de comando atual :

convert -trim -density 400 this_is_a_very_long_filename_of_my_pdf_file.pdf !#:$:r.png
  • Designador de evento !# refere-se à linha de comando digitada até o momento
  • O designador de palavras $ indica a última palavra (antes da expansão)
  • Modifier r remove a extensão do arquivo. Isso também marca o final do texto, que é substituído quando ocorre a expansão do histórico.
  • .png é a nova extensão. Isso não pertence à expansão em si.

Quando esta linha é executada, !#:$:r é substituído pelo nome do seu arquivo pdf menos a extensão, criando assim o comando a partir da pergunta:

convert -trim -density 400 this_is_a_very_long_filename_of_my_pdf_file.pdf this_is_a_very_long_filename_of_my_pdf_file.png

Esta linha é então executada diretamente.

Se você quiser verificar o comando após a expansão do histórico, antes da execução, use

setopt histverify

Isso recarregará a linha expandida no buffer de edição em vez de executá-la.

Nota: Diferentemente de qualquer outra expansão, a expansão de histórico é executada antes que o comando seja salvo no histórico. Então, echo !# aparecerá como echo echo e não como echo !# no seu $HISTFILE .

    
por 08.07.2014 / 09:12
2

Não é possível derrotar a expansão de chaves neste exemplo especial. No entanto, um pouco mais flexível é o widget zle copy-prev-shell-word , que faz o que o nome sugere e é útil se você quiser um argumento similar como o anterior, que não pode derivar sistematicamente dele.

Vincule o widget, por exemplo para CTRL+W :

bindkey '^W' copy-prev-shell-word

Se você é tão preguiçoso quanto eu, use esta seqüência de teclas

bindkey '^W^W' copy-prev-shell-word
bindkey -s '^W' ' ^W^W'

para obter o seguinte comportamento:

  • CTRL+W insere a palavra shell anterior com um espaço em branco (portanto, você salva um pressionamento de tecla!)
  • CTRL+W CTRL+W insere a palavra-chave anterior diretamente
por 10.07.2014 / 22:31