Shell Scripting: como usar parte do caminho do arquivo como nome do arquivo?

Shell Scripting: como usar parte do caminho do arquivo como nome do arquivo?

Eu tenho um grupo de diretórios, cada um contendo exatamente 1 imagem JPEG, como assim-

/psds/folder1/image.jpg
/psds/someotherfolder/picture.jpg
/psds/yetanotherfolder/thumbnail.jpg

Qual é a maneira apropriada de renomear os jpegs para o nome da pasta que os contém? O que eu quero é:

/psds/folder1/folder1.jpg
/psds/someotherfolder/someotherfolder.jpg
/psds/yetanotherfolder/yetanotherfolder.jpg

Responder1

Execute os comandos abaixo dentro /psdsdo diretório.

for f in ./*; do
    if [ -d "$f" ] ; then
        cd "$f"
        mv *.jpg "$f.jpg"
        cd ..
    fi
done

Se você tiver 3 pastas dentro /psdsdo diretório como abaixo,

/psds/folder1/image1.jpg
/psds/folder2/image2.jpg
/psds/folder3/image3.jpg

Depois de executar o comando acima, os arquivos serão renomeados como,

/psds/folder1/folder1.jpg
/psds/folder2/folder2.jpg
/psds/folder3/folder3.jpg

Responder2

Você pode usar oexpansão de parâmetro shellconstruções ${VAR#PREFIX}e ${VAR%SUFFIX}para obter o valor de uma variável com o prefixo ou sufixo especificado removido. Se PREFIX for um padrão, a string correspondente mais curta será removida; com ##ou %%, a correspondência mais longa será removida. Essas construções estão disponíveis em todos os shells do tipo sh (Bourne/POSIX), não apenas no bash.

Se o valor de VARfor um caminho como /path/to/directory/file, então "${VAR%/*}"é o diretório que contém o arquivo e "${VAR##*/}"é o nome do arquivo sem a parte do diretório. Observe que isso "${VAR%/*}"só está correto se $VARcontiver pelo menos um /e "${VAR##*/}"somente se VARnão terminar com /. Existem também utilitários chamados dirnamee basenameque são mais confiáveis ​​nesse aspecto. Da mesma forma ${VAR##*.}é a última extensão.

for x in /psds/*/*.jpg; do
  dir="${x%/*}"
  mv "$x" "$dir/${dir##*/}.jpg"
done

Como sempre, o zsh tem um jeito um pouco enigmático, mas curto e doce. OzmvA função é conveniente para renomear arquivos em massa.

autoload -U zmv   # put this in your .zshrc
zmv '/psds/(*)/*.jpg' '/psds/$1/$1.jpg'

Outra abordagem usandomodificadores de expansão de históricona expansão de parâmetros:

zmv '/psds/*/*.jpg' '$f:h/$f:h:t.$f:e'

informação relacionada