Скрипты оболочки: как использовать часть пути к файлу в качестве имени файла?

Скрипты оболочки: как использовать часть пути к файлу в качестве имени файла?

У меня есть группа каталогов, каждый из которых содержит ровно одно изображение в формате JPEG, например:

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

Как правильно переименовать jpeg-файлы в имя папки, в которой они находятся? Мне нужно следующее:

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

решение1

Выполните следующие команды внутри /psdsкаталога.

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

Если у вас есть 3 папки внутри /psdsкаталога, как показано ниже,

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

После выполнения указанной выше команды файлы будут переименованы следующим образом:

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

решение2

Вы можете использоватьрасширение параметра оболочкиконструкции ${VAR#PREFIX}и ${VAR%SUFFIX}для получения значения переменной с указанным отсеченным префиксом или суффиксом. Если PREFIX является шаблоном, то отсеивается самая короткая совпадающая строка; с ##или %%вместо этого отсеивается самая длинная совпадающая строка. Эти конструкции доступны в каждой оболочке sh-type (Bourne/POSIX), а не только в bash.

Если значение VAR— это путь типа /path/to/directory/file, то "${VAR%/*}"— каталог, содержащий файл, а "${VAR##*/}"— имя файла без части каталога. Обратите внимание, что "${VAR%/*}"это правильно только в том случае, если $VARсодержит хотя бы один /, и "${VAR##*/}"только если VARне заканчивается на /. Также существуют утилиты, называемые dirnameи , basenameкоторые более надежны в этом отношении. Аналогично ${VAR##*.}и с последним расширением.

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

Как обычно, zsh имеет немного загадочный, но короткий и приятный способ.zmvфункция удобна для массового переименования файлов.

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

Другой подход с использованиеммодификаторы расширения историипо расширению параметров:

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

Связанный контент