재귀 디렉토리에서 구체적으로 명명 된 폴더를 추출하는 방법, 다른 것을 삭제 하시겠습니까?


10

zip 파일을 압축 해제하여 얻은 디렉토리 트리 종류가 있습니다.

x-> y-> z-> 실행 -> 여기에서 파일 및 디렉토리

따라서 4 개의 디렉토리가 있으며 그 중 3 개는 파일이 비어 있고 (x, y, z) 하나의 하위 디렉토리 만 포함하며, 관심있는 디렉토리는 " run "입니다.

"run"디렉토리 자체 (내부 모두 포함)를 압축을 푼 "루트"위치 (예 : "x"는 있지만 "x"내부는 아님)로 이동하고 싶습니다.

가정 : "run"이라는 이름의 폴더 있지만, "cd"로 가져와야하는 디렉토리 수는 3 개 (x, y, z), 10 개 이상일 수 있습니다. 또한 알려지지 않았으며 x, y, z 등일 필요는 없습니다).

어떻게하면 되나요? 나는 이 질문에 대한 많은 변형을 시도 했지만 모두 실패했습니다.


1
나는 사진이 명확하지 않다는 것을 두려워한다. 텍스트 스크린 샷을 게시하지 마십시오 . 대신 텍스트를 질문에 직접 붙여넣고 서식 도구를 사용하십시오 . 나는 당신의 사진에서 디렉토리 이름을 읽을 수 없습니다. 내가 보는 것은 희미한 파란색 흐림입니다.
terdon

답변:


14

이건 어떤가요

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

어디

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

(사이드 노트에는 --junk-paths압축 또는 압축 해제시 지퍼 옵션이 있습니다)


7

에서 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디렉토리 가 하나 뿐인 경우에만 작동 함 )를 이동 x하고 find비어있는 디렉토리를 삭제합니다.

원하는 경우 확장 globbing으로 쉘에서 모든 작업을 수행 할 수 있지만 find -empty비어 있지 않은 디렉토리가 삭제되지 않도록 안전망을 선호합니다 . 신경 쓰지 않으면 다음을 사용할 수 있습니다.

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

6

확실히 더 장황하지만 한 단계로 작업을 수행합니다.

파이썬이 설치되었다고 가정

#!/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
    

그리고 그것은 이루어집니다 :

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오


이것은 매우 흥미로운 해결책이지만 여러 가지 이유로 파이썬 스크립트를 사용하지 않는 것을 선호합니다. 고마워요!
Idos

문제 없어요. 어쩌면 다른 사람에게도 유용 할 것입니다. 왜 궁금하십니까? 많은 응용 프로그램이 이미 파이썬을 사용하고 있다고 확신합니다.
Jacob Vlijm

주로 .py 파일을 어디에나 두는 것이 문제가 될 수 있기 때문에 스크립트를 실행할 모든 Linux 시스템에서 동일한 위치에 있어야한다고 가정해야하므로 스크립트는 여러 플랫폼에서 실행됩니다.
Idos

@Idos가 궁금한 플랫폼은 무엇입니까? 파이썬은 꽤 널리 퍼져 있습니다. 나는 그것이 기본적으로 맥 OS X에 설치되어 있다고 생각하지 않지만, 대부분의 리눅스 배포판에는 그것을 가지고있다
Sergiy Kolodyazhnyy

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()하여 File::Copy::Recursive스크립트가 호출 된 현재 작업 디렉토리로 이동합니다. 따라서 귀하의 경우 부모 디렉토리에서로 호출합니다 x.

원본 디렉토리 트리 :

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

결과:

$ ~/find_dir.pl .  
$ tree 
.
├── levelone
│   └── leveltwo
│       └── levelthree
└── run
    ├── file1
    ├── file2
    └── file3
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.