리눅스 특정 폴더 및 파일 제외 명령어?

리눅스 특정 폴더 및 파일 제외 명령어?

QA

리눅스 특정 폴더 및 파일 제외 명령어?

본문

에를 들어,

현재폴더에서 data 폴더와 config.php 파일을 제외하고 모두 삭제하고자 할 때

어떤 식으로 명령어를 입력해주면 되는지?

이 질문에 댓글 쓰기 :

답변 8


// php 로 만들어 보았습니다.
class Remove {
    public $scanned_dir = array();
    public $result = array();
    function __construct() {
        $this->scanned_dir = $this->scan_dir('*');
    } 
    function scan_dir($pattern, $flags = 0) {
        $files = glob($pattern, $flags);
        foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) 
            $files = array_merge($files, $this->scan_dir($dir.'/'.basename($pattern), $flags)); 
        return $files;
    }
    function remove($remain_dir, $remain_file) { 
        foreach ($this->scanned_dir as $file) { 
            if (basename(__FILE__) == $file) continue;
            $flag = true;
            if (is_dir($file)) {
                foreach ($remain_dir as $v) {
                    if (strpos($file, $v) !== false) {
                        $flag = false;
                        break;
                    } 
                }
                if ($flag) rmdir($file);
            } else {
                foreach ($remain_dir as $v) {
                    if (preg_match("#/$v#", $file)) {
                        $flag = false;
                        break;
                    } 
                }
                foreach ($remain_file as $v) {
                    if ($v == $file) {
                        $flag = false;
                        break;
                    } 
                }
                if ($flag) unlink($file);
            }
            if ($flag) $this->result[] = $file;
        }
        $this->show();
    }
    function show() { 
        echo implode('<br>', $this->result);
    }
}
 
$remain_dir = array('a', 'b', 'data');
$remain_file = array('c.txt', 'config.txt');
$rm = new Remove();
$rm->remove($remain_dir, $remain_file);

테스트 해보니 아래 사항 빼고 아주 잘 작동하네요.

예를 들어,
오직 data 폴더만 남기려는데, data 복사본 폴더까지 함께 남네요.
(예) data-a , data a, data_a 등등등...

오직 data 폴더만 남기려는 경우와,
data라는 글자가 들어간 경우를 구별하는 기능이 들어가면 더 좋을 것 같습니다. ^^


덕분에 삭제 쉽게 할 수 있게 되어 너무 기분 좋네요.
요새, 감동의 연속입니다. ㅎ

// 수정본입니다.
class Remove {
    public $scanned_dir = array();
    public $result = array();

    function __construct() {
        $this->scanned_dir = $this->scan_dir('*');
    }

    function scan_dir($pattern, $flags = 0) {
        $files = glob($pattern, $flags);
        foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR) as $dir)
            $files = array_merge($files, $this->scan_dir($dir.'/'.basename($pattern), $flags));
        return $files;
    }

    function remove($remain_dir, $remain_file) {
        foreach ($this->scanned_dir as $file) {
            if (basename(__FILE__) == $file) continue;
            $flag = true;
            if (is_dir($file)) {
                foreach ($remain_dir as $v) {
                    if (strpos('/' . $file . '/', '/' . $v . '/') !== false) {
                        $flag = false;
                        break;
                    }
                }
                if ($flag)
                    $this->delTree($file);                       
            } else {
                if (file_exists($file)) {
                    foreach ($remain_dir as $v) {
                        if (preg_match("#/$v#", $file)) {
                            $flag = false;
                            break;
                        }
                    }
                    foreach ($remain_file as $v) {
                        if ($v == $file) {
                            $flag = false;
                            break;
                        }
                    }
                    if ($flag) unlink($file);
                }
            }
            if ($flag)
                $this->result[] = $file;
        }
        $this->show();
    }

    function delTree($dir)    {
        $files = glob($dir . '*', GLOB_MARK);
        foreach ($files as $file) {
            is_dir($file) ? $this->delTree($file) : unlink($file);             
        }     
        if (is_dir($dir) && file_exists($dir)) rmdir($dir);
    }

    function show() {
        echo implode('<br>', $this->result);
    }
}

$remain_dir = array('k', 'data');
$remain_file = array('c.txt', 'config.txt');
$rm = new Remove();
$rm->remove($remain_dir, $remain_file);

슈와이 님,
방금 실제로 제 서버에 올려 실행해보니, 약간 덜 삭제되는 게 있네요.

$remain_dir = array('data'); // 보존할 폴더
$remain_file = array(); // 보존할 파일

오직 data 폴더만 남게 설정 후 실행시켰더니, 아래 폴더들이 남아있네요.
FTP로 접속해 지우면 쉽게 삭제되긴 하는데, 기왕이면....다홍치마라.. ^^;;

a/hz/a/aa.php  ....테스트차 만들어둔 폴더와 그 안의 파일들
extend 폴더 ... 안의 내용물은 삭제된 상태인데, 폴더는 그대로 남음.
plugin 폴더 ... 대부분 삭제되었는데, 일부 이상한 확장자 파일 하나씩 남은 폴더들이 삭제 안 됨

대충 추론하건데, 폴더 안에 이런 이상한 확장자 파일이 삭제 안 되어 남는 듯 합니다.
.htaccess
.gitignore
.travis.yml

// .htaccess 타입의 파일 삭제 추가
// 제약사항 : .github 타입의 폴더는 처리하지 못함

class Remove {
    public $scanned_dir = array();
    public $result = array();

    function __construct() {
        $this->scanned_dir = $this->scan_dir("{,.}*", GLOB_BRACE);
    }

    function scan_dir($pattern, $flags = 0) {
        $files = glob($pattern, $flags);
        foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR) as $dir)
            $files = array_merge($files, $this->scan_dir($dir.'/'.basename($pattern), $flags));
        return $files;
    }

    function remove($remain_dir, $remain_file) { 
        for ($i=count($this->scanned_dir)-1; $i>=0; $i--) {
            if (preg_match('/\.(\.)?$/', $this->scanned_dir[$i]) || basename(__FILE__) == $this->scanned_dir[$i]) continue;
            if ($this->find_dir($remain_dir, $this->scanned_dir[$i])) continue;

            $flag = true;
            if (is_file($this->scanned_dir[$i]) && !$this->find_file($remain_file, $this->scanned_dir[$i]))
                unlink($this->scanned_dir[$i]);
            else if (is_dir($this->scanned_dir[$i]))
                rmdir($this->scanned_dir[$i]);     
            else
                $flag = false;
           
            if ($flag) $this->result[] = $this->scanned_dir[$i];
        }
        $this->show();
    }

    function find_file($remain_file, $file) {
        foreach ($remain_file as $v) 
            if (basename($file) == $v) return true;           

        return false;
    }

    function find_dir($remain_dir, $file) {
        foreach ($remain_dir as $v)
            if (strpos('/' . $file . '/', '/' . $v . '/') !== false) return true;
       
        return false;
    }

    function show() {
        echo implode('<br>', $this->result);
    }
}

$remain_dir = array('data');
$remain_file = array('c.txt');
$rm = new Remove();
$rm->remove($remain_dir, $remain_file);

http://blog.naver.com/PostView.nhn?blogId=beahey&logNo=90097133614

참고하시면 될것 같습니다.

혹시 모르니 백업후 실행하시는게 좋을거 같습니다.

그러면 이글 참조해보십시요.

http://forum.falinux.com/zbxe/index.php?document_srl=850930&mid=lecture_tip&order_type=desc&sort_index=regdate

 

적어진대로 해봤는데, 안 되는 것 같아요.

aa라는 폴더를 만들고 그 안에 들어가서 아래 폴더와 파일들을 만들었습니다.
a
a.php
b
b.php
c
c.php

find . ! -path "./a*" ! -path "./b*" | cut -d "." -f2 | cut -d "/" -f2 | xargs rm -rf {} \;
위 명령어를 aa 폴더 안에서 넣었는데, 전혀 변화가 없네용.

위험하게 리눅스에서하지마시고 대부분폴더를지우실꺼면..그냥 FTP로 DATA폴더 받아서 

윈도우에서 그냥 필요없는애들 다지우고 쓸애들만 업로드후 권한설정하는게 편하실수도있어요~

서버는잘모를때 잘못만지면 다날라가니 ㅎㅎ 

find . ! -name 'config.php' -type f -exec rm -f {} +
특정 파일 (Config.php)를 제외하고 삭제합니다 -rf 로 바꾸시면 디렉토리도 삭제 가능할거라보입니다.

죄송합니다 글의 의미를 제대로 파악하지 못했네요.

find [path] -type f -not -name 'textfile.txt' -not -name 'backup.tar.gz' -delete

계속 -not -name 을 추가하시는 방법도 있고..

find . -type f -not -name '*txt' -print0 | xargs -0 rm --

이경우에는 확장자 별로 분류가 가능합니다.

 

톄스트를 해보니, 약간 불안정 한 것 같네요.

a
a.php
b
b.php
c
c.php

이렇게 있는 상태에서 아래 명령어를 실행했더니,


find . -type f -not -name 'a' -not -name 'a.php' -delete


a
a.php
b

가 남네요. b까지 삭제돼야 정상 같은데....

ps.
관심 갖고 답변 달아주신 것만으로도 감사합니다. ^^

답변을 작성하시기 전에 로그인 해주세요.
전체 123,619 | RSS
QA 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT