web-dev-qa-db-ja.com

パス名でファイル名を変更する

サブフォルダ内に.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
7
sh999

そのためには、mcp( "multiple move")パッケージのmmvツールを使用します。

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

2番目の文字列の#1#2などは、最初の文字列の対応する1番目、2番目などのワイルドカードの内容に置き換えられます。パスは一重引用符で囲まれているため、ワイルドカードはシェルではなくmcpによって解釈されることに注意してください。

コマンドが表示されると、ファイルは現在のディレクトリにコピーされます。 mcpmmvに置き換えると、代わりにファイルが移動されます。

10
Dubu

他の回答の一部で言及されているツール(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

このスクリプトは、oldpathディレクトリでLoad.bdfという名前のすべてのファイルを検索し、ディレクトリ名を新しいファイル名に変更して、宛先ディレクトリにコピーします。また、複数回実行する必要があり、すべてのファイルを再度コピーする必要がない場合に備えて、すでにコピーされたファイルの存在を確認することもできます。

結果のディレクトリ構造は、次のようになります。

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
3
Tim Kennedy

Zshでは zmv を使用すると簡単です。

autoload -U zmv
cd /home/user
zmv '*/*/*' '${1//\//_}'
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

これはすべて完全に移植可能なシェルスクリプトだと思います。最初は疑問がありましたが、かなり簡単に実行できました。

0
mikeserv