모든 유형의 파일을 찾아 {another_dir}/{dir_files_are_at}/{file}로 이동하는 방법은 무엇입니까?

모든 유형의 파일을 찾아 {another_dir}/{dir_files_are_at}/{file}로 이동하는 방법은 무엇입니까?

나는 많은 파일과 그 안에 텍스트 파일을 포함하는 많은 디렉토리를 가지고 있습니다. 이렇게 생겼어

MainDir
|------dir1
|       |-------file1
|       |-------file2
|       |-------file3.txt
|------dir17
|       |-------file23
|       |-------file34
|       |-------file52.txt
|       |-------file65

각 디렉토리의 파일 수는 무작위이며 txt 파일이 1개이거나 없습니다.
모든 txt 파일을 MainDir 내의 "txtFiles" 디렉터리로 이동해야 하며, 각 txt 파일은 원본 디렉터리와 동일한 이름을 가진 하위 디렉터리에 있어야 합니다(txtFiles 디렉터리의 하위 디렉터리는 존재하지 않으므로 생성해야 합니다.) 이것이 다음과 같아야합니다

MainDir
|------dir1
|       |-------file1
|       |-------file2
|------dir17
|       |-------file23
|       |-------file34
|       |-------file65
|------txtFiles
|       |-------dir1
|       |        |-------file3.txt
|       |-------dir17
|       |        |-------file52.txt

find 명령어로 할 수 있는 방법이 있나요?

또한 일부 파일 및 디렉터리 이름에는 공백이 포함되어 있습니다!

답변1

$ tree
.
`-- MainDir
    |-- dir1
    |   |-- notes.txt
    |   |-- some_file-1
    |   |-- some_file-2
    |   `-- some_file-3
    `-- dir17
        |-- README.txt
        |-- some_file-1
        |-- some_file-2
        `-- some_file-3

3 directories, 8 files

사용 rsync:

$ rsync -a --include '*.txt' --exclude '*/*' MainDir/ MainDir/txtFiles/
$ tree
.
`-- MainDir
    |-- dir1
    |   |-- notes.txt
    |   |-- some_file-1
    |   |-- some_file-2
    |   `-- some_file-3
    |-- dir17
    |   |-- README.txt
    |   |-- some_file-1
    |   |-- some_file-2
    |   `-- some_file-3
    `-- txtFiles
        |-- dir1
        |   `-- notes.txt
        `-- dir17
            `-- README.txt

6 directories, 10 files

이 명령은 파일 이름 접미사가 있는 --include '*.txt'모든 파일을 포함 하고 다른 파일을 제외하는 데 사용됩니다 . 또는 를 사용하면 소스 계층의 복사된 부분 복사본이 대상에 생성됩니다..txt--exclude '*/*'-a--archive

이 명령을 다시 실행하면 MainDir/txtFiles/txtFiles빈 디렉터리가 생성됩니다. 통화에 또는 를 추가하면 -m이를 방지할 수 있습니다.--prune-empty-dirsrsync


사용 find( 내에서 MainDir):

$ find . -type f -name '*.txt' ! -path '*/txtFiles/*' \
    -exec sh -c 'for n; do
                     d="txtFiles/${n%/*}";
                     mkdir -p "$d" && cp "$n" "$d"
                 done' sh {} +

*.txt그러면 디렉토리 에 없지만 이름이 일치하는 txtFiles모든 일반 파일을 찾습니다 .

발견된 각 파일 이름 경로에 대해 경로의 디렉터리 부분이 해당 경로 아래에 생성되고 txtFiles파일이 거기에 복사됩니다.

rsync이 방법과 이 방법의 유일한 차이점은 rsync주어진 이름과 일치하는 비전통적인 파일을 복사할 수 있다는 것입니다(파이프라는 이름의 디렉터리 등) find.~ 해야 하다내부에서 실행합니다 MainDir.

관련 정보