シェルスクリプト:ファイルパスの一部をファイル名として使用するには?

シェルスクリプト:ファイルパスの一部をファイル名として使用するには?

次のように、正確に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

/psds以下のようにディレクトリに3つのフォルダがある場合

/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がパターンの場合、または##を使用して最短の一致文字列を削除し、%%最も長い一致文字列を削除します。これらの設定は、bashだけでなく、すべてのsh-type(Bourne / POSIX)シェルで利用できます。

値がVARそのようなパスの場合は、ファイルを含むディレクトリであり、/path/to/directory/fileディレクトリ部分がないファイル名です。これは、少なくとも1つを含み、次に終わらない場合にのみ正確です。これに関して、より信頼できるユーティリティもあります。最後の拡張も同じだ。"${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'

関連情報