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'

相關內容