web-dev-qa-db-ja.com

ファイル名を親フォルダ名に置き換えます

それぞれ独自のサブディレクトリにたくさんのファイルがあります。各ファイルの名前をディレクトリと同じ名前に変更するスクリプトを作成する必要があります。たとえば、次のように指定します。

./1111/1234.pdf
./2222/2345.pdf
./1234/3214.pdf

名前を次のように変更する必要があります。

./1111/1111.pdf
./2222/2222.pdf
./1234/1234.pdf

どうやってやるの?

2
Duy

シェルがzshであると仮定して、autoload -U zmv~/.zshrcに入れ、実行します。

zmv '(*)/*.pdf' '$1/$1.pdf'

次のbashスクリプトは、親ディレクトリで呼び出されたときにジョブを実行します。すべてのファイルの拡張子が同じではない場合でもそうなります(限られた例ではそうですが、それは偶然かもしれません)。

#!/bin/bash
function dirnametofilename() {
  for f in $*; do
    bn=$(basename "$f")
    ext="${bn##*.}"
    filepath=$(dirname "$f")
    dirname=$(basename "$filepath")
    mv "$f" "$filepath/$dirname.$ext"
  done
}

dirnametofilename ./????/*

そこでの呼び出しは、現在のディレクトリのサブディレクトリにある4文字の名前のファイルを想定しています。最後の行を次のものと交換できます。

dirnametofilename $*

スクリプトのパラメータとしてファイル名を指定します


以下は、やや深い階層を作成し、findを使用してファイルを検索します。 export -fbashによって開始されたfindが関数について知っていることを確認します。

mkdir -p x/y/z/1111 x/y/z/2222 x/y/z/1234
touch x/y/z/1111/1234.pdf
touch x/y/z/2222/2345.pdf
touch x/y/z/1234/3214.pdf

function dirnametofilename() {
  for f in $*; do
    bn=$(basename "$f")
    ext="${bn##*.}"
    filepath=$(dirname "$f")
    dirname=$(basename "$filepath")
    mv "$f" "$filepath/$dirname.$ext"
  done
}

export -f dirnametofilename

find . -name "*.pdf" -exec bash -c 'dirnametofilename "{}"'  \;
# and look at the result
find x
2
Anthon
echo ./1111/1234.pdf | Perl -pe '$_.=$_; s/\/(.*?)\/.+\.(.*?)$/\/$1\/$1\.$2/' | xargs -n 2 mv
0
yuni