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
)。
スペースを節約するためにコピーの代わりにリンクを作成するか、またはln
(ln -sr
GNU-r
拡張ですが組み込みzsh
サポートされていません)を使用できます。ln
cp