Bash - Manipulação Contínua de Cordas

11
#!/bin/bash

FILE="$(basename "$1")"
FILE="${FILE/%.jpeg/.jpg}"

Existe alguma maneira de colar essas duas linhas em uma linha?

gsklee
fonte

Respostas:

12

FILE=$(basename "${1/%.jpeg/.jpg}") trabalhou para mim.

teste:

bash-$ ./test.sh /tmp/foo.jpeg
foo.jpg

conteúdo do script:

bash-$ cat test.sh 
#!/usr/bin/bash

FILE=$(basename "${1/%.jpeg/.jpg}")

echo "$FILE"
Tim Kennedy
fonte
Como as duas linhas são meio intercambiáveis, essa solução é até agora a mais arrumada ... Se as linhas não forem intercambiáveis sedserão definitivamente necessárias, eu acho.
gsklee
11

Você não pode aninhar expansões no bash (nem no ksh, ash e outras conchas além do zsh). Essa é apenas uma limitação cosmética, pois, como você ilustra, pode atribuir uma expressão intermediária a uma variável temporária. É um pouco chato para as falas, mas nos scripts é indiscutivelmente melhor para facilitar a leitura.

Você pode evitar o uso do utilitário externo basenamee, em vez disso, usar uma construção de manipulação de string:

FILE="${1##*/}"; FILE="${FILE/%.jpeg/.jpg}"

Aqui, você pode reescrever seu script para colocar a substituição de comando do lado de fora . Esse não é um fenômeno geral, e você não ganha nada além de um certo sentimento de uma linha.

O Zsh, para o bem ou para o mal, permite aninhar expansões:

FILE=${$(basename $1)/%.jpeg/.jpg}    # using basename
FILE=${${1##*/}/%.jpeg/.jpg}          # using string rewriting

Ou você pode usar a construção interna do zsh em vez de basename:

FILE=${${1:t}/%.jpeg/.jpg}
Gilles 'SO- parar de ser mau'
fonte
4

Eu iria para:

FILE=$(basename $1 .jpeg).jpg

O segundo parâmetro para basename é um sufixo a ser removido do nome do arquivo (consulte man basename)

Chirlo
fonte
3

Você pode usar um único sedcomando como no seguinte:

FILE=$(sed 's/.*\///;s/\.jpeg$/.jpg/' <<<"$1")
enzotib
fonte
2

Incorporando sed, isso deve fazer o truque:

FILE="$(basename "$1" | sed s/\.jpeg$/.jpg/)"

(Isso não responde exatamente à sua pergunta porque não posso; não tenho certeza se é possível.)

sr_
fonte
1

As ${}construções do Bash funcionam com nomes de variáveis , portanto, não há como incorporar um comando diretamente. A abordagem do @ sr_ é uma alternativa se você não se importa com o garfo extra.

l0b0
fonte
1

A linha

FILE=$(basename "${1/%.jpeg/.jpg}")

pode ser reduzido e tornado mais portátil com

FILE=$(basename "${1%.jpeg}.jpg")
Peter John Acklam
fonte