디렉토리 구조에서 선택한 파일을 중복 디렉토리의 심볼릭 링크로 복사하려고 합니다.
다음과 같은 디렉토리 구조에서:
../1/a/data1.txt
../1/a/file1.txt
../1/a/b/file2.txt
이 작업을 수행:
../2/a/file1.txt -> ../../1/a/file1.txt
../2/a/b/file2.txt -> ../../2/a/b/file1.txt
예를 들어 디렉터리 트리를 유지하고 다양한 패턴과 일치하는 파일을 건너뜁니다.
GNU cp를 사용하여 대상 디렉터리(../2/a)의 상대 경로를 바꾸면 data1.txt를 복사한다는 점을 제외하면 모든 것이 원하는 대로 작동합니다.
gcp -rs $(cd ../..; pwd)/1/a/* $PWD/
하지만 특정 파일을 제외하기 위해 find + xargs에서 이를 사용하면,
find -X -f $(cd ../..; pwd)/1/a \! -name '*data*' -type f | xargs -t -n1 -I % gcp -s -t $PWD/ %
알겠어요:
../2/a/file1.txt -> ../1/a/file1.txt
../2/a/file2.txt -> ../1/a/b/file2.txt
예를 들어 디렉터리 구조는 복사되지 않습니다. 지루한 해결 방법을 상상할 수 있지만 xargs 구문에서 중요한 것이 누락된 것 같습니다. (특정 날짜 이전과 이후의 파일은 다르게 처리되기 때문에 찾기를 이용하고 싶습니다.)
내 솔루션대략적으로 서브쉘을 호출하고, 경로를 생성하고, 디렉토리를 생성하고, 링크를 생성합니다(예: 여기 예제에서는 테스트되지 않음).
find $(cd ../..; pwd) -type f \! -name '*data*' -print0 | xargs -0 bash -c
'while [ -n "$1" ]; do
TMP="${1%$(basename $1)}";
mkdir -p "${TMP/1/2}";
gcp -s "$1" "${1/1/2}";
shift;
done;' "bash"
이것은 스크립트 내에서 호출되기 때문에 명령 앞에 관련 경로 이름을 내보냈습니다(여기서 "1"과 "2"는 실제로 $PATH1, $PATH2입니다. 이 예에서는 $1의 b/c는 "1"입니다. "2"는 혼란스럽습니다.")
답변1
-r
매개변수 없이 디렉터리를 반복적으로 복사하면 cp
중간 디렉터리가 생성되지 않습니다. (단순히 추가하는 것은 -r
작동하지 않습니다. 소스가 디렉토리가 아니면 아무런 효과가 없습니다.)
-r
GNU의 옵션 ln
("상대 링크 만들기") 을 시도하고 예를 사용할 수 있습니다 mkdir -p {dirname}
.
# usage mklinks from to [opts/predicates for find ..]
mklinks(){
from=$1; shift
to=$1; shift
find "$from" -type f "$@" -print0 | from=$from to=$to gxargs -0 sh -c '
for a; do
t="$to/${a#$from}"; b=${t##*/}
mkdir -vp "${t%$b}" && gln -vrs "$a" "$t"
done
' sh
}
mklinks ../../1/a . \! -name '*data*'
물론, Linux를 사용한다면 and gxargs
로 변경하세요 xargs
.gln
ln