이 cli 명령에 디렉토리 생성을 어떻게 추가할 수 있습니까?

이 cli 명령에 디렉토리 생성을 어떻게 추가할 수 있습니까?

디렉토리를 순회하면서 하위 디렉토리를 찾고, 특정 파일을 찾아 다른 곳에 복사하고 있습니다. 다음을 수행하고 있습니다.

for i in `ls ./*/filename`; do cp $i ../test2; done

이것은 모든 파일 이름을 가져와 test2 디렉토리로 이동합니다... 문제는 소스 디렉토리 이름도 필요하다는 것입니다... awk로 이 작업을 수행할 수 있다고 생각하지만 전혀 모르고 어려움을 겪고 있습니다...

for i in `ls ./dirname/filename`; do cp ../test2/dirname/; done

디렉토리에 있는 모든 파일이 필요하지 않기 때문에 전체 디렉토리 이름을 복사할 수 없습니다.

답변1

특정 파일이나 디렉터리의 전체 디렉터리 경로를 다른 디렉터리로 복사하려면 최소한 두 가지 옵션이 있습니다.

cpGNU coreutils 에서 다음을 사용하십시오 --parents.

cp --parents ./*/sourcefile /some/path/destdir

rsync, 사용 -R또는 --relative:

rsync -R ./*/sourcefile /some/path/destdir

예를 들어 여기에 표시된 명령 ./a/sourcefile으로 복사하기 위해 대상 디렉터리의 소스 경로 아래에 각 소스 파일이 배치됩니다 ./some/path/destdir/a/sourcefile

이 작업을 수행할 때 파일을 반복할 필요가 없습니다.

cpGNU가 없는 시스템에서는 rsync루프를 실행할 수 있지만 루프의 출력을 원하지 않습니다 ls. 대신에

for pathname in ./*/sourcefile; do
    destdir="/some/path/destdir/$(dirname "$pathname")"
    mkdir -p "$destdir" && cp "$pathname" "$destdir"
done

이것은 복사하려는 모든 파일을 반복하며 각 파일에 대해 해당 대상 디렉토리가 있는지 확인한 다음 거기에 파일을 복사합니다.

예:

$ tree
.
|-- dest
`-- src
    |-- a
    |   |-- file
    |   `-- something-else
    |-- b
    |   |-- file
    |   `-- something-else
    |-- c
    |   |-- file
    |   `-- something-else
    |-- d
    |   |-- file
    |   `-- something-else
    `-- e
        |-- file
        `-- something-else

7 directories, 10 files

여기에 위의 두 명령(또는 루프) 중 하나를 입력합니다. 소스는 이고 ./src/*/file대상은 입니다 ./dest.

$ tree
.
|-- dest
|   `-- src
|       |-- a
|       |   `-- file
|       |-- b
|       |   `-- file
|       |-- c
|       |   `-- file
|       |-- d
|       |   `-- file
|       `-- e
|           `-- file
`-- src
    |-- a
    |   |-- file
    |   `-- something-else
    |-- b
    |   |-- file
    |   `-- something-else
    |-- c
    |   |-- file
    |   `-- something-else
    |-- d
    |   |-- file
    |   `-- something-else
    `-- e
        |-- file
        `-- something-else

13 directories, 15 files

답변2

이를 수행하려면 rsync -R(--relative) 플래그를 사용해 보십시오:

$ for i in ls ./*/filename; do rsync -avR $i ../test2; done

-R 플래그는 명령줄에 제공된 전체 경로를 동기화합니다.

관련 정보