폴더 구조를 유지하면서 특정 파일 형식 복사


108

폴더에 흩어져있는 * .csv 파일이있는 폴더 구조가 있습니다. 이제 모든 * .csv 파일을 폴더 구조를 유지하면서 다른 대상으로 복사하고 싶습니다.

다음을 수행하여 작동합니다.

cp --parents *.csv /target
cp --parents */*.csv" /target
cp --parents */*/*.csv /target
cp --parents */*/*/*.csv /target
...

등등.하지만 하나의 명령을 사용하여하고 싶습니다.

답변:


126

사람들이 find를 사용하는 것을 거부하는 이유가 -exec있습니까? 매우 편리합니다.

find . -name '*.csv' -exec cp --parents \{\} /target \;

도구를 아십시오. ;-)


62
아마도 이것 때문에 \ {\} \;
igo

12
'{}'마찬가지로 작동
OrangeDog

3
-execdir보다 안전 하지만 -exec, 단순히 하나를 다른 것으로 바꾸어도 의도 한대로 폴더 구조가 유지되지는 않습니다.
Simon Shine

2
명령으로 복사하려고 할 때 '디렉터리 생략'메시지가 나타나는 이유는 무엇입니까?
Vicky Dev

4
여기서 중괄호를 탈출해야하는 이유를 설명 할 수 있습니까?
Noumenon

46

rsync이것을 위해 사용할 수도 있습니다 .

$ rsync -a --prune-empty-dirs --include '*/' --include '*.csv' --exclude '*' source/ target/

소스 트리에서 빈 디렉토리를 유지하려면 --prune-empty-dirs옵션을 건너 뜁니다 .

$ rsync -a --include '*/' --include '*.csv' --exclude '*' source/ target/

심볼릭 링크, 수정 날짜, 파일 권한, 소유자 등을 보존 하지 않으 려면 -a다른 조합으로 바꾸십시오 -rlptgoD. ;-)


1
-m에 대한 바로 가기입니다 --prune-emty-dirs.
Geremia

또한 -R소스의 상위 디렉토리 구조를 복사하기 위해 옵션을 추가 할 수 있습니다. (cf. 내 답변은 여기에 있습니다.)
Geremia

-R은 나를 위해 일한다! 감사합니다
gigi2

32

통과 모드에서 findcpio 를 사용할 수 있습니다

find . -name '*.csv' | cpio -pdm  /target

이것은 현재 디렉토리와 그 아래에서 모든 .csv 파일을 찾아서 루트로 지정된 디렉토리 구조를 유지하면서 / target에 복사합니다 ..

당신이 사용하는 경우

find /path/to/files -name '*.csv' | cpio -pdm /target

모든 파일을 /path/to/files아래 에서 찾아서 아래로 복사합니다 /target/path/to/files.


3
나는 모든 답을 이것에 이르기까지 시도했는데 이것이 첫 번째 시도에서 작동 한 유일한 질문입니다
OscarRyz

21

cp명령은 여러 소스 인수를 허용합니다.

cp **/*.csv --parents ../target

주의 사항 : 저는 여기 재귀 글로브를 사용하고 있습니다. 이것은 globstarBash 4+ 및 의 옵션이며 ksh기본적으로에서 지원됩니다 zsh. 재귀 글로브 숨겨진 파일 및 폴더와 일치 하지 않으며 일부 구현은 심볼릭 링크를 따르지만 다른 구현은 그렇지 않습니다 .

쉘이 재귀 글로브를 지원하지 않거나 사용하지 않으려면 다음을 수행하십시오.

  • *.csv */*.csv */*/*.csv */*/*/*.csv -이것은 물론 매우 중복되며 디렉토리 구조의 깊이를 알아야합니다.
  • $(find . -name '*.csv')-이 됩니다 숨김 파일 및 폴더를 일치합니다. find또한 심볼릭 링크를 따를 지 여부를 지정하는 데 도움이되므로 유용 할 수 있습니다.

이것은 내가 시도한 것 (재귀 글로브)이며 전부는 아니지만 일부를 찾았습니까? 꽤 이상합니다. npm copyfiles 스크립트를 사용할 때와 동일한 결과를 얻었지만 find 명령을 사용하면 모든 것을 찾습니다.
Randyaa

@Randyaa 나는 당신을 돕기 위해 찾을 수없는 파일에 대한 자세한 내용이 필요합니다. 여기서 재귀 글로브의 정확한 동작에 대한 토론을 찾을 수 있고 여기서 계속할 수 있습니다 .
Kyle Strand

1
어떤 이유로 든 재귀 글로브가 활성화되지 않은 것으로 나타났습니다 ...이 전에는 실행 한 적이 없지만 shopt -s globstar명령 바로 직전에 실행하여 모든 문제를 해결했습니다 . 후속 감사합니다!
Randyaa

--parents내가 찾던 것이 었습니다. 감사합니다
Josh

17

이것은 나를 위해 일했다 :

find -name "*.csv" | xargs cp --parents -t /target


가장 간단한 구문으로 최상의 답변. 잘 작동하고 기억하기 쉽습니다. 많은 경우 find [things] | xargs [do stuff]에 매우 강력합니다.
매일 우주 비행사

동의했다. 다른 답변에 비해 매우 간단합니다.
팀 B

1
파일 이름에 공백이 있으면
중단

@MichelePiccolini 파일 이름의 공백은 find -print0및 로 처리 할 수 ​​있습니다 xargs -0.
pasztorpisti

8

이 구조를 ./source에서 ./destination다음 으로 복제한다고 가정합니다 .

cd source
find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)

나는 그것을 한 줄로 셀 수 있도록 준비했습니다 cd source.


2
나는 그가 실제로 하나의 명령을 의미한다고 생각하지 않습니다-단지 그의 예처럼 좋아할 필요가 없습니다.)

tar-C디렉토리를 먼저 변경하지 않아도 되는 옵션이 있습니다.
bart

8

에서 rsync의 맨 :

-R,-상대

상대 경로를 사용하십시오. 이는 명령 행에 지정된 전체 경로 이름이 파일 이름의 마지막 부분이 아닌 서버로 전송됨을 의미합니다. 이것은 여러 개의 다른 디렉토리를 동시에 보내려는 경우에 특히 유용합니다. 예를 들어,이 명령을 사용한 경우 :

rsync -av /foo/bar/baz.c remote:/tmp/

... 이것은 원격 시스템의 / tmp /에 baz.c라는 파일을 만듭니다. 대신에

rsync -avR /foo/bar/baz.c remote:/tmp/

그러면 /tmp/foo/bar/baz.c라는 파일이 전체 경로를 유지하면서 원격 시스템에 작성됩니다. 이러한 추가 경로 요소를 "암시 적 디렉토리"(예 : 위 예에서 "foo"및 "foo / bar"디렉토리)라고합니다.

따라서 이것은 작동합니다.

rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.