名前に基づいて複数のフォルダにファイルをコピーする

名前に基づいて複数のフォルダにファイルをコピーする

x/y/z/Drawingsと同じ名前の複数レベルの入れ子になったフォルダがありますa/b/c/x/y/z/Plans。パスのどこかにフォルダーDrawingsまたはPlansサブフォルダーを含む数百の親フォルダーがあります。

Drawings.jpg次に、とというアイコンがありますPlans.jpg。正しいJPGをすべての正しい(つまり適切な名前付き)サブフォルダにコピーしたいと思います。つまり、各フォルダについてフォルダ階層のどこにあっても、およびファイルを../Drawings見たいと思います。../Drawings/Drawings.jpg../Plans/Plans.jpg

Whatever.jpg私はUbuntuで実行されており、名前という名前の各サブフォルダに名前付きファイルをコピーする方法を見つけることができませんsomething/something/Whatever。問題は、デフォルトでは、フォルダ名に基づいて単一のファイルソースを複数の宛先の1つにコピーすることです。

適切に保存する必要があるJPGは15個以下ですが、各JPGには数百のターゲットサブフォルダがあります。

一連の簡単なcpコマンドを使用してこれを達成できますか?それとも、目的の結果を生成できるBashスクリプトはありますか?

答え1

リーフではなく、ディレクトリをコピーコマンドの候補として考えるため、ソリューションの基盤をfind

iconDir=/path/to/icons_directory
rootDir=/path/to/top/of/drawings_projects_etc

find "$rootDir" -type d -exec sh -c '
    iconDir="$0"
    for thisDir in "$@"
    do
        iconName="${thisDir##*/}.jpg"
        [ -f "$iconDir/$iconName" ] && echo cp -p "$iconDir/$iconName" "$thisDir"
    done
' "$iconDir" {} +

$rootDirこれが行うことは、以下の各ディレクトリを順番に考慮することです。$iconDirディレクトリパスの最後の部分(サフィックス)に対応する場所でアイコンファイルを探し、.jpg見つかったらターゲットディレクトリにコピーします。

作成したとおり、意図した操作の説明のみを取得できます。実際にファイルをコピーできるようにechoプレフィックスを削除します。cp

cp -p代わりにcp権限を保存し、 - 多くの場合、より便利に - 元のファイルのタイムスタンプを使用します。あなた$iconDirとすべての$rootDirツリーが同じファイルシステムにあるln場合cp -p

答え2

そしてzsh

for icon (path/to/icons/*.jpg(N.))
  for dir (path/to/dirs/**/$icon:t:r(N/))
    cp $icon $dir/

作業速度を上げるためにさまざまな最適化を実行できます。

  • path/to/dirsまず、すべてのディレクトリのリストを作成し、それを再利用して各アイコンのディレクトリツリーをクロールする必要はありません。
  • makebuildin はcpプロセスを分岐し、各コピーに対して外部コマンドを実行するコストを排除します。
  • 実際、ここではグローブをソートする必要はないので、グローブをNソートしないでください。o
  • ここでは、バイト間比較で十分なので、マルチバイト文字サポートを無効にします。

だから

zmodload zsh/files
set +o multibyte
dirs=(path/to/dirs/**/*(N/oN))
for icon (path/to/icons/*.jpg(N.oN))
  for dir (${(M)dirs:#*/$icon:t:r})
    cp $icon $dir/

(最も重要なのは、zmodload zsh/files組み込みを有効にすることですcp)。

スペースを節約するためにコピーの代わりにリンクを作成するか、またはlnln -srGNU-r拡張ですが組み込みzshサポートされていません)を使用できます。lncp

関連情報