많은 하위 디렉터리가 포함된 디렉터리가 있습니다. 그러므로
/usr/local/src/ccl/ccl-1.8/x86-headers$ ls
elf gl gmp gnome2 gtk2 jni libc
C
각 디렉토리에는 파일이 포함된 하위 디렉토리가 있습니다 populate.sh
. 동일한 구조를 가진 병렬 하위 디렉토리 세트를 생성하고 싶지만 디렉토리 이름 뒤에 임의의 값을 추가하고 싶습니다(임의의 값은 모든 경우에 동일해야 함). 파일이 있는 C 하위 디렉터리만 포함됩니다 populate.sh
. 이러한 디렉터리에는 populate.sh
이 파일 외에 다른 파일이 포함되어 있습니다.
이는 makefile용이므로 단순화를 위해 표준 Unix 유틸리티를 사용해야 합니다. 해당 -exec
플래그를 사용하여 찾거나 작동할 생각이지만 xargs
문서를 이해하는 데 문제가 있고 쉘 스크립팅에 대한 경험이 거의 없습니다. Perl이 작동할 수도 있지만 저는 그것을 사용해 본 적이 없으며 여기서는 사용하고 싶지 않습니다.
mktemp -u --tmpdir=.
과거에도 비슷한 접근 방식을 사용하여 임의의 문자열을 생성했지만 이상적이지 않으므로 다른 제안을 받아들일 수 있습니다. 이상적으로는 그런 이름을 짓고 싶습니다 libc.tmp_xw3st
. 즉. tmp_
그 뒤에는 5자리 영숫자 문자열이 옵니다.
지금까지 나는 최상위 디렉토리 목록을 얻는 방법을 찾았습니다. :-)
find . -maxdepth 1 -type d -print0
../gmp./jni./gl./elf./libc./gtk2./gnome2
보다 완전한 디렉토리 목록은 이 기사의 끝에 있습니다. 전체적으로 나는 x86-headers/libc.tmpvalue
추가 파일만 포함하는 다른 디렉토리를 만들고 싶습니다 x86-headers/libc.tmpvalue/C/populate.sh
.
한 가지 가능한 접근 방식에 대한 개요는 다음과 같이 두 단계로 이 문제를 처리하는 것입니다.
1단계: 최상위 디렉터리 목록을 순회하고 을 사용 하거나 파이프로 연결 하고 사용하는 find
등 해당 디렉터리 구조를 만드는 데 사용합니다 .dirname.tmpvalue/C/
exec
xargs
mkdir -p
2단계: 최상위 디렉터리 목록을 다시 실행하고 하위 디렉터리 populate.sh
로 cp를 실행합니다 C
. 이론적으로 디렉토리 목록은 호출 사이에 변경될 수 있으므로 이는 약간 엉성 find
하지만 이 경우에는 문제가 되지 않습니다.
/usr/local/src/ccl/ccl-1.8/x86-headers$ ls -laR
[...]
./jni:
total 96
drwxr-sr-x 3 faheem staff 4096 Jul 31 00:53 .
drwxr-sr-x 9 faheem staff 4096 Jul 31 00:53 ..
drwxr-sr-x 2 faheem staff 4096 Jul 31 00:53 C
-rw-r--r-- 1 faheem staff 19535 Jul 31 00:53 constants.cdb
[more .cdb files]
./jni/C:
total 12
drwxr-sr-x 2 faheem staff 4096 Jul 31 00:53 .
drwxr-sr-x 3 faheem staff 4096 Jul 31 00:53 ..
-rw-r--r-- 1 faheem staff 148 Jul 31 00:53 populate.sh
./libc:
total 1276
drwxr-sr-x 3 faheem staff 4096 Jul 31 00:53 .
drwxr-sr-x 9 faheem staff 4096 Jul 31 00:53 ..
drwxr-sr-x 2 faheem staff 4096 Jul 31 00:53 C
-rw-r--r-- 1 faheem staff 593125 Jul 31 00:53 constants.cdb
[more .cdb files]
./libc/C:
total 20
drwxr-sr-x 2 faheem staff 4096 Jul 31 00:53 .
drwxr-sr-x 3 faheem staff 4096 Jul 31 00:53 ..
-rwxr-xr-x 1 faheem staff 10544 Jul 31 00:53 populate.sh
답변1
find
재귀가 포함되지 않기 때문에 작동하지 않습니다 .
for x in */C/populate.sh; do
mkdir -- "${x%%/*}$suffix"
mkdir -- "${x%%/*}$suffix/C"
cp -p -- "$x" "./${x%%/*}$suffix/C"
done
파일 수정 시간을 보존하지 않으려면 이 -p
옵션을 제거하세요.cp
임의 접미사 생성, BSD/Linuxmktemp
가능한 한 휴대성이 좋습니다.
suffix=$(mktemp -u tmp_XXXXX)
막연하게 무작위로 보이고 POSIX와 호환되는 것을 원하는 경우 매초 변경되고 위치에 따라 달라지는 문자열이 제공됩니다. POSIX 도구만으로는 이보다 더 나은 결과를 얻을 수 없습니다.
suffix=$({ hostname; pwd; date; } |
cksum | uuencode -m /dev/stdin | awk 'NR==2 {print substr($0,3,5)}')
이 코드를 makefile에 넣는 경우 다음 사항을 기억하세요.
- 모든 징후가 두 배로 증가했습니다
$
. - 구분된 셸 명령 대신을 사용하여 모든 코드를 한 줄에 입력합니다
;
(백슬래시+줄바꿈+탭을 사용하여 makefile에 줄바꿈을 넣을 수 있지만 해당 시퀀스는 셸 명령을 빌드할 때 제거됩니다). set -e
오류가 발생하면 중단하기 위해 쉘 조각을 시작합니다 .
답변2
다음을 사용하여 각 최상위 디렉터리의 복사본을 만들 수 있습니다.
$ find . -maxdepth 1 -type d -exec mkdir {}".tmpvalue" \;
그런 다음 파일을 반복하여 .sh
각 디렉터리에 복사할 수 있습니다.
답변3
다음과 같이 시도해 보세요.
#!/bin/sh
# Create a temporary partial clone of the current directory
tcopy=`mktemp -d /tmp/tmp_XXXXX`
tbase=`basename $tcopy`
find . -name populate.sh -print | cpio -pud "$tcopy"
# Randomize the clone
for d in "$tcopy"/*
do
mv "$d" "$d.$tbase"
done
# Merge the clone back into the current tree
mv "$tcopy"/* .
mv
이는 파일 시스템 간에 전체 디렉토리를 이동하는 방법을 아는 구현 에 따라 다릅니다 . GNU는 mv
작동하지만 마지막 줄이 작동하지 않는 일부 오래된 Unix 시스템에서 작업했던 기억이 납니다. find | cpio
이 경우 다른 채널을 이용하시면 됩니다. mv
작동한다면 더 효율적일 것입니다.
답변4
find
다른 사람이 결과를 복사하고 중간 디렉터리를 만드는 방법을 찾고 있다면 --parents
GNU cp
, rsync -R
또는 pax -rw
를 사용할 수 있습니다 cpio -pd
.
find . -type f -exec cp --parents -t /tmp {} +
--parents creates intermediate directories in GNU cp
-t specifies a target directory in GNU cp
find . -type f -print0|xargs -0I, rsync -R , /tmp
-R is --relative
find . -type f|pax -rw /tmp
-rw (read and write) copies files
pax is required by POSIX but not LSB and not included by some Linux distributions
find . -type f|cpio -pdu /tmp
-p (pass-through) copies paths from stdin to a specified directory
-d creates intermediate directories
-u unconditionally overwrites existing files