パス名を使用したファイル名の変更

パス名を使用したファイル名の変更

サブフォルダに.bdfファイルがあります。すべての.bdfの名前はLoads.bdfと同じです。

例:

/home/user/folderxx/folderxxx/Load.bdf
/home/user/folderxx/folderxxx/Load.bdf

すべてのLoad.bdfファイルを見つけて新しいフォルダにコピーし、パス名に名前を変更する必要があります。

例: 予想される操作の後、次のように表示する必要があります。

folder001_folderAAA_Load.bdf
folder002_folderBBB_Load.bdf

答え1

("Multiple Moves")パッケージmcpのツールを使用します。mmv

mcp '/home/user/*/*/Load.bdf' '#1_#2_Load.bdf'

#12番目の文字列の等価は、最初の文字列の対応する1#2番目、2番目などのワイルドカード文字の内容に置き換えられます。ワイルドカードがmcpシェルではなくシェルで解釈されるように、パスを一重引用符で囲みます。

表示されたコマンドを使用すると、ファイルは現在のディレクトリにコピーされます。mcpに置き換えるとmmvファイルが移動されます。

答え2

これは実行しないか、次の方法で複数回実行できますprename(多くのシステムでエイリアスとして使用されます)。renamemvcp

cd /home/user
find . -type f -name 'Loads.bdf' -exec \
  prename -n 's:^./::; s:/:_:g; s:^:destination/:' {} +

-n目的のファイルが移動されていると確信している場合は、削除してください。

修正する

ファイルを移動するのではなくコピーするには、最初にまたはをcpio使用してコピーしてから、以前のようpaxに名前を変更するのが最速の方法です。たとえば(GNUを使用cpio):

cd /home/user
find . -type f -name 'Loads.bdf | cpio -p --make-directories destination

cd destination
find . -type f -name 'Loads.bdf' -exec  prename -n 's:^./::; s:/:_:g' {} +

paxPOSIXとLSBであり、cpioPOSIXではなく、まだcpio多くのシステムで一般的なプログラムです。

find改行でGNU /ハンドルファイル名を使用するには、toとtoをcpio追加します。-print0find-0cpio

アップデート2

解決策paxは1行です(含まれていませんcd)。

cd /home/user
find . -name 'Loads.bdf' | cut -d/ -f 2- | pax -rws ':/:_:g' destination

またはファイル名(およびGNU)の場合find

find /home/user -name 'Loads.bdf' -printf '%P\0' | pax -0rws ':/:_:g' destination

答え3

他の答え(mcp、mmv、prenameなど)で言及されているツールがないシステムでこれを行う必要があり、シェルで完全に実行したい場合は、次のようにします。 :

#!/usr/bin/env bash

oldpath="/home/user"
newpath="/home/user/newfolder"

for file in $(find $oldpath -type f -name Load.bdf); do
        shortname=${file#$oldpath/}
        newname="$newpath/${shortname//\//_}"
        if [ -f $newname ]; then
                echo "$newname already exists."
        else
                echo "copy: $file"
                echo "  --> $newname"
                cp $file $newname
        fi
done

Load.bdfこのスクリプトは、ディレクトリで指定されたすべてのファイルを検索し、ディレクトリoldpath名を新しいファイル名にマージしてからターゲットディレクトリにコピーします。複数回実行し、すべてのファイルを再コピーする必要がない場合に備えて、コピーされたファイルが存在することを確認することもできます。

最終的なディレクトリ構造は次のとおりです。

bash$ find . -type f
/home/user/folder001/folderAAA/Load.bdf
/home/user/folder002/folderBBB/Load.bdf
/home/user/folder003/folderCCC/Load.bdf
/home/user/newfolder/folder001_folderAAA_Load.bdf
/home/user/newfolder/folder002_folderBBB_Load.bdf
/home/user/newfolder/folder003_folderCCC_Load.bdf

答え4

env - sh <<\SCRIPT

    t=/home/user/target f=folder
    cd "${t%/*}" && mkdir -p "$t"
    set -- $f??/$f???/Load.BDF
    while [ -e "$1" ] ; do
        cp "$1" "$t/$(IFS=/
            printf '%s_%s_%s\n' $1)"
    shift ; done

SCRIPT

私はこれがすべて完全に移植可能なシェルスクリプトだと思います。最初は懐疑的でしたが、完了するのはとても簡単でした。

関連情報