유닉스-PATTERN을 제외한 파일 및 폴더 삭제


10

최근에 특정 패턴과 일치하는 파일을 제외하고 디렉토리의 모든 파일 / 폴더를 삭제하는 작업에 직면했습니다. 그래서 작업을 수행하기 위해 한 줄짜리 유닉스 명령을 만들었습니다. 한 줄만되어야합니까? 나는 그렇지 않다고 생각하지만, 그런 식으로 확실히 더 시원합니다!

문제는 매우 간단하지만 솔루션이 얼마나 복잡한 지에 약간 놀랐습니다. 내가 사용한 명령은 다음과 같습니다. 참고 : 이것은 줄 바꿈 문자가 포함 된 파일 이름을 처리하지 않기 때문에 좋지 않은 솔루션입니다 (내 상황에서는 중요하지 않음).

ls | grep -v PATTERN | xargs -n1 -IREPLACE rm -rf REPLACE

PATTERN과 일치하는 폴더로 재귀를 원하지 않기 때문에 "find"명령을 사용하지 않았습니다. 예를 들어, 다음 파일 구조를 고려하십시오.

file_foo.txt
first_dir
  |
  +--> contents
  +--> ...
foo_dir
  |
  +--> anotherfile.txt
  +--> morefiles.log
foo_file.txt
somefile.txt

패턴 "foo는"을 사용하면 전용 "first_dir"(물론 그것의 내용)와 "somefile.txt"(제거해야 하지 "anotherfile.txt"또는 "morefiles.log을").

질문, 이것을 달성하는 더 나은 (더 우아하고 올바른) 방법이 있습니까?


편집 :
최근에 "찾기"가 더 나은 옵션 일 수 있다는 것이 주목되었습니다 .

find * -maxdepth 0 ! -name PATTERN -print0 | xargs -0n1 rm -rf

이 솔루션은 줄 바꿈 문자가 포함 된 경로를 올바르게 처리합니다.


편집 : 잘못된 "the_dir"을 올바른 "first_dir"로 변경했습니다.
joxl

답변:


10

다음 예제는 echo실제로 사용하기 전에 패턴을 테스트 할 수 있도록 접두어를 붙였습니다. 를 제거 echo을 활성화 rm -rf. rm -ri확인 메시지를 대체 합니다.

ksh 는 globbing에 대해 음의 일치 확장을 갖습니다.

# ksh
echo rm -rf !(*foo*)

옵션 을 설정하면 bash 에서 동일한 구문을 사용할 수 extglob있습니다.

# bash
shopt -s extglob
echo rm -rf !(*foo*)

zsh 는이를위한 고유 한 구문을 가지고 있습니다.

# zsh
setopt extended_glob
echo rm -rf ^*foo*

ksh 스타일 구문을 사용할 수도 있습니다 .

# zsh: ksh-style glob syntax
setopt ksh_glob no_bare_glob_qual
echo rm -rf !(*foo*)

# zsh: ksh-style glob syntax, adapted for the default bare_glob_qual option
setopt ksh_glob bare_glob_qual
echo rm -rf (!(*foo*))

간단한은, 우아한, 손잡이 줄 바꿈 문자는 (거의) 한 줄 (내가 추가 한 shopt -s extglob지금, 그래서 내의 .bashrc 파일 입니다 한 - 라이너). 완전한! 나는 나의 명성이 허락하자마자 공감대를 약속한다.
joxl

7

다른 find해결책이 있습니다. 나는 이것이 당신보다 실질적인 이점을 가지고 있다고 확신하지는 않지만, xargs너무 많은 이름으로 확장 될 수있는 드문 가능성을 필요로하지 않으며 허용합니다.

find . -maxdepth 1 ! -name PATTERN -type f -delete

또한 -type f디렉토리를 삭제하려고 시도하지 않도록 추가 했습니다.

경고 : -delete강력합니다. 테스트 파일 중 하나에 0 권한을 부여했으며 위의 명령이 주저없이 삭제했습니다.


6
먼저 테스트하십시오. 교체 -delete-print당신이 원하는 파일을 찾는 것 있는지. 모든 것이 좋으면 명령 기록을 사용하여 (예 : 위로 버튼 누름) 이전 명령으로 돌아가서 동일한 찾기 필터로 작업하고 있는지 확인하십시오.
더그 해리스

주의 깊게 읽고 디렉토리를 제거 하고 싶습니다. 그리고 find -delete비어 있지 않은 디렉토리를 제거하지 않습니다. 또한 find -maxdepth 1"."와 일치합니다. (현재 디렉토리) 정말 나쁩니다. 를 제거하려는 아이디어가 마음에 들지만 대안 적으로 xargs사용할 수 있습니다 find -exec. find * -maxdepth 0 ! -name PATTERN -exec rm -rf '{}' \;
joxl

0

이 rebol 스크립트 예제 http://askcodegeneration.com/keep-subversion/을 대신 사용하면 훨씬 이해하기 쉽고 폴더 선택 및 확인과 같은 사용자 상호 작용을 관리 할 수 ​​있습니다.

delete-file: func[file][
    if/else none? find file "/.svn/" [
        delete file
    ][
        print ["keeping" file]
    ]
]
dir: request-dir
ans: ask rejoin ["Do you confirm " dir "? (Yes): "]
if (ans = "Yes") [
    foreach-file dir :delete-file
]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.