명령 줄에서 *에서 제외


14

*예를 들어 rm -rf *수천 개의 하위 폴더와 파일이 들어 있는 폴더에서 a를 사용하는 것이 불가피한 상황이 많이 있습니다.

그러나 rm명령 에서 하나 또는 두 개의 파일 또는 폴더 만 제외하려면 어떻게해야 합니까? 나는 길을 훑어 보았고 여기에find . -depth -not \( -name 'one' -o -name 'two' \ -o -name 'three' \) -exec rm {} \; 언급 된 것처럼 매우 복잡한 해결책 만 찾았습니다 .

이 우회없이 더 쉬운 방법 으로이 작업을 수행 할 수 find있습니까? 예를 rm -rf --exclude='one' --exclude='two' --exclude='three' *들어 rsync 또는 그냥 rm -rf -e 'one','two','three' *?

어쩌면 일반적인 가능성에서 일 제외 *(그래서 다른 명령이 좋아을 cp, mv... 자신을 구현할 필요가 없습니다)? 좋아하는 것 *{'one','two','three'}?


3
하나 또는 두 개의 파일 만 유지하려면 가장 간단하고 쉬운 방법은 해당 파일을 다른 위치로 옮기고 나머지 파일을 모두 지우고 보관 한 파일을 옮기는 것입니다. 더 많은 파일을 유지 find하려면 --delete옵션 과 함께 사용 하십시오 ( rm각 파일마다 실행할 필요가 없습니다 . 오버 헤드는 필요 없습니다).
Hennes

그것은 가능할 것이지만, 내가 언급 한 것만큼이나 정교합니다. 나는 명령어를 같은 것으로 결합 할 수 있다는 것을 알고 mv -t /tmp one two three && rm -rf * && mv -t . /tmp/one /tmp/two /tmp/three있지만, 무언가 를 명시 적으로 제외시킬 수있는 솔루션을 선호한다 *. 파일을 다른 대상으로 이동하거나 복사하는 것이 옵션이 아닌 상황이있을 것입니다.
David

2
그렇기 때문에 답변으로 게시하지 않았습니다. 단순히 일을 수행하는 덜 복잡한 방법 (세 개의 매우 간단한 명령 대 하나의 다소 복잡한 명령). 나는 rm과 함께 복잡성을 싫어.
Hennes

답변:


33

Bash에는 표준 쉘 구문과의 호환성을 유지하기 위해 기본적 으로 비활성화되는 쉘 옵션 extglob이 있습니다. Extglob은 추가와 같은 사업자 구문을 보완 , , 좀 더합니다.!()?()@()

전원을 켜려면을 extglob입력하십시오 shopt -s extglob. 현재 사용자 유형에 대해 켜진 상태로 유지합니다 echo 'shopt -s extglob' >> ~/.bashrc.

RM은 예를 들어 :로에게 extglob당신이 사용할 수있는

rm -rf !(one|two|three)

좋은 해결책처럼 보이지만 설명 된 것과 같은 상황에 처할 때마다 스위치를 켜고 끄고 싶지 않습니다.
David

3
@David : 당신은 shopt물건을 넣을 ~/.bashrc수 있습니다.
enzotib

내가 올바르게 얻으면 extglob 옵션은 전혀 효과를 변경하지 *않지만 대신 추가 기능이있는 유사한 지표를 !추가합니까? 이 경우 멋진 솔루션이 될 것입니다.
David

1
@David : 맞습니다.
choroba

1
@David 표준 쉘 구문과의 호환성을 유지합니다 . 행동이 바뀔 수있는 다른 상황이있을 수 있습니다.
gerrit

4

나는 그것을 제외하고 는 지어졌습니다 (아직 문서를 추가 할 수 없었습니다.)

다음과 같은 폴더가 있습니다.

$ ls
a b c d

타자가 except b d당신에게 줄 것이다 ac

$ except b d
ac

이제 이것을 파이프에 연결할 수 있습니다 rm.

except b d | xargs -0 rm

이것은 기억하기 어려울 수 있으므로 다음을 제외하고 스크립트를 작성하지 마십시오 rm-except.

#!/usr/bin/env bash

except "$@" | xargs -0 rm

비슷하게 쉽습니다 ls-except:

#!/usr/bin/env bash

except "$@" | xargs -0 ls

3
이것은 좋지만 extglob에 대해 알 때 실제로 필요하지는 않습니다.- askubuntu.com
David

1

extglob에 대한 대안으로 (아주 좋은 답변이며 모든 사람이 shopt -s extglob globstar.bashrc에 있어야 함 ) $ GLOBIGNORE 전역 변수를 사용할 수 있습니다 . 'foo.txt'및 'bar baz.txt'를 제외한 모든 파일을 가져오고 싶다고 가정 해 봅시다.

GLOBIGNORE=foo.txt:'bar baz.txt'

그러나 쉘 옵션 dotglob을 켜면 *점으로 시작하는 파일 (보통 숨겨져 있음)과 일치합니다. 따라서 실제로 두 가지 명령이 필요합니다.

GLOBIGNORE=foo.txt:'bar baz.txt'
shopt -u dotglob

이것은 전역 변수이므로 $ GLOBSTAR가 로그 아웃되거나 다음과 같이 설정 해제 될 때까지 사용하는 모든 glob에 영향을줍니다.

GLOBIGNORE=

또한 변수에 전달 된 리터럴 문자열에서만 작동합니다. $ GLOBIGNORE를 설정하고 다음 명령의 차이점을 살펴보면 무슨 뜻인지 알 수 있습니다.

printf '%s\n' *
printf '%s\n' ./*
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.