재귀 디렉터리에서 특정 이름의 폴더를 추출하고 다른 폴더를 삭제하려면 어떻게 해야 합니까?

재귀 디렉터리에서 특정 이름의 폴더를 추출하고 다른 폴더를 삭제하려면 어떻게 해야 합니까?

zip 파일의 압축을 풀어 얻은 다음과 같은 디렉토리 트리가 있습니다.

x -> y -> z ->달리기-> 파일과 디렉토리는 다음과 같습니다.

따라서 4개의 디렉토리가 있습니다. 그 중 3개는 빈 파일(x,y,z)이고 하위 디렉토리는 1개만 포함되어 있습니다. 그리고 제가 관심을 갖고 있는 디렉토리는 "달리기".

"실행" 디렉터리 자체(그 안의 모든 항목 포함)를 압축을 푼 "루트" 위치(예: "x"는 있지만 "x" 내부는 아님)로 이동하고 싶습니다.

가정: 예존재하다"run"이라는 폴더가 있지만 폴더에 도달하기 위해 "cd"해야 하는 디렉터리 수는 모르겠습니다(아마도 3(x,y,z), 어쩌면 10개 이상). 이름도 알 수 없으며 폴더에 포함되지 않습니다. x, y, z 등일 필요는 없습니다.)

어떻게 해야 하나요? 다양한 변형을 시도했습니다이 문제그러나 그들은 모두 실패했습니다.

답변1

무엇에 대해

  find . -type d -name run -exec mv {} /path/to/X \;

어디

  • /path/to/X는 대상 디렉토리입니다.
  • 같은 곳에서 시작합니다.
  • 그런 다음 다른 답변을 사용하여 빈 디렉토리를 삭제하십시오.

(BTW --junk-paths, 압축하거나 압축을 풀 때 zip 옵션이 있습니다)

답변2

나는 bash이것을 하곤 했다 globstar. 설명된 대로 man bash:

globstar
      If set, the pattern ** used in a pathname expansion con‐
      text will match all files and zero or  more  directories
      and  subdirectories.  If the pattern is followed by a /,
      only directories and subdirectories match.

따라서 디렉터리를 run최상위 수준으로 이동한 x후 나머지를 삭제하려면 다음을 수행합니다.

shopt -s globstar; mv x/**/run/ x/  && find x/ -type d -empty -delete

shopt명령을 사용하면 이 globstar옵션이 활성화됩니다. mv x/**/run/ x/지정된 모든 하위 디렉터리 run(디렉토리가 하나만 있는 경우에만 작동함 ) run가 이동되고 빈 디렉터리 xfind삭제됩니다.

원하는 경우 확장된 와일드카드를 사용하여 셸에서 모든 작업을 수행할 수 있지만 find -empty비어 있지 않은 디렉터리가 삭제되지 않도록 하는 안전망을 선호합니다. 이에 대해 신경 쓰지 않으면 다음을 사용할 수 있습니다.

shopt -s globstar; shopt -s extglob; mv x/**/run/ x/ && rm -rf x/!(run)

답변3

확실히 더 자세하지만 작업은 한 단계로 완료됩니다.

파이썬이 설치되어 있다고 가정

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]

for root, dirs, files in os.walk(dr):
    # find your folder "run"
    for pth in [d for d in dirs if d == sys.argv[2]]:
        # move the folder to the root directory
        shutil.move(os.path.join(root, pth), os.path.join(dr, pth))
        # remove the folder (top of the tree) from the directory
        shutil.rmtree(os.path.join(dr, root.replace(dr, "").split("/")[1]))

사용하는 방법

  1. 스크립트를 빈 파일에 복사하고 다른 이름으로 저장하세요.get_folder.py
  2. 루트 디렉터리(압축 해제된 내용 포함)와 "리프트"하려는 폴더 이름을 인수로 사용하여 실행합니다.

    python3 /full/path/to/get_folder.py /full/path/to/folder_containing_unzipped_dir run
    

그게 다야 :

여기에 이미지 설명을 입력하세요.

여기에 이미지 설명을 입력하세요.

답변4

펄 솔루션

#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
use File::Copy::Recursive qw(dirmove);

my @wanted;
find(sub{ -d $_ && $_ eq "run" && push @wanted,$File::Find::name}, $ARGV[0]);
dirmove("$wanted[0]","./run");

작동 방식은 간단합니다. find()서브루틴은 지정된 디렉토리 트리를 재귀적으로 탐색하고 이름이 지정된 디렉토리를 찾아 run필요한 파일 이름 배열에 푸시합니다. 이 경우 목록에는 파일이 하나만 있어야 한다고 가정하므로 명령이 완료되면 dirmove()from File::Copy::Recursive모듈을 사용하여 호출 스크립트의 현재 작업 디렉터리로 이동합니다. 따라서 귀하의 경우 상위 디렉토리에서 x.

원래 디렉토리 트리:

$ tree                                                                                                                   
.
└── levelone
    └── leveltwo
        └── levelthree
            └── run
                ├── file1
                ├── file2
                └── file3

결과:

$ ~/find_dir.pl .  
$ tree 
.
├── levelone
│   └── leveltwo
│       └── levelthree
└── run
    ├── file1
    ├── file2
    └── file3

관련 정보