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
. 문제는 기본적으로 폴더 이름을 기반으로 단일 파일 소스를 여러 대상 중 하나로 복사하는 것입니다.
적절하게 저장해야 하는 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
( -r
GNU 확장이지만 zsh
내장 지원 되지 않음) 을 사용할 수 있습니다 .ln
cp