Shell脚本:如何使用部分文件路径作为文件名?

Shell脚本:如何使用部分文件路径作为文件名?

我有一组目录,每个目录恰好包含 1 个 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

您可以使用shell参数扩展构造${VAR#PREFIX}${VAR%SUFFIX}获取去掉指定前缀或后缀的变量的值。如果 PREFIX 是模式,则删除最短的匹配字符串;使用##or %%,最长的匹配项将被删除。这些构造在每个 sh 类型 (Bourne/POSIX) shell 中都可用,而不仅仅是 bash。

如果 的值VAR是类似 的路径/path/to/directory/file,则"${VAR%/*}"是包含该文件的目录,并且"${VAR##*/}"是不带目录部分的文件名。请注意,仅当至少包含一个且不以 结尾时"${VAR%/*}"才是正确的。还有一些名为和 的实用程序在这方面更可靠。最后一个扩展也是如此。$VAR/"${VAR##*/}"VAR/dirnamebasename${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'

相关内容