unix/linux 쉘에서 패턴을 일치시킬 때 어떻게 역 또는 음의 와일드카드를 사용할 수 있습니까?
이름에 '음악'이라는 단어가 포함된 파일 및 폴더를 제외한 디렉토리의 내용을 복사하려고 합니다.
cp [exclude-matches] *Music* /target_directory
이를 위해 [제외 매치]대신 무엇을 해야 합니까?
에서는 Bash를 활성화하여 수행할 수 있습니다.extglob
이렇게 선택지를 만들어 보세요.ls
와와 with와 함께요.cp
을 사용하세요.)
~/foobar> shopt extglob
extglob off
~/foobar> ls
abar afoo bbar bfoo
~/foobar> ls !(b*)
-bash: !: event not found
~/foobar> shopt -s extglob # Enables extglob
~/foobar> ls !(b*)
abar afoo
~/foobar> ls !(a*)
bbar bfoo
~/foobar> ls !(*foo)
abar bbar
나중에 다음을 사용하여 extglob을 비활성화할 수 있습니다.
shopt -u extglob
»는 다음과 같습니다.extglob
셸 옵션을 사용하면 명령줄에서 보다 강력한 패턴 매칭을 수행할 수 있습니다.
같같켜켜로 거예요.shopt -s extglob
그리고 끄면 됩니다.shopt -u extglob
요.
이 예에서는 처음에 다음을 수행합니다.
$ shopt -s extglob
$ cp !(*Music*) /target_directory
사용 가능한 전체 확장 글로벌 연산자는 다음과 같습니다(에서 제외).man bash
다음을 수행합니다.
shopt builtin을 사용하여 extglob 쉘 옵션을 활성화하면 여러 확장 패턴 일치 연산자가 인식됩니다.pattern-list는 |로 구분된 하나 이상의 패턴 목록입니다.복합 패턴은 다음 하위 패턴 중 하나 이상을 사용하여 형성될 수 있습니다.
- 리스트(패턴 리스트)라고 합니다.
지정된 패턴의 0 또는 1회 발생과 일치합니다.- *(pattern-list)*(패턴 목록)입니다.
지정된 패턴의 발생 횟수가 이상이면 일치합니다.- +(패턴 리스트)+(패턴 리스트)라고 합니다.
지정된 패턴의 하나 의 발생과 일치합니다.- )@(pattern-list)라고 합니다.
주어진 패턴 중 하나와 일치합니다.- )!(pattern-list)라고 합니다.
지정된 패턴 중 하나를 제외한 모든 패턴과 일치합니다.
따라서예를 들어 현재 디렉터리에 있는 파일 중 예가 아닌 모든 파일을 나열하려는 경우에는 현을 수 있습니다..c
아니면요?.h
이겁니다.
$ ls -d !(*@(.c|.h))
물론 일반 셸 글로잉은 작동하므로 마지막 예제는 다음과 같이 쓸 수 있습니다.
$ ls -d !(*.[ch])
(제가 알기로는) bash는 아니지만요.
cp `ls | grep -v Music` /target_directory
이게 당신이 찾던 것이 아니라는 걸 알지만, 당신의 사례를 해결할 수 있을 거예요.
exec 명령어를 사용하는 데 드는 mem 비용을 피하고 싶다면 xargs로 더 잘 할 수 있을 것입니다.다음 사항이 보다 효율적인 대안이라고 생각합니다.
find foo -type f ! -name '*Music*' -exec cp {} bar \; # new proc for each exec
find . -maxdepth 1 -name '*Music*' -prune -o -print0 | xargs -0 -i cp {} dest/
아직 서 본 적이 없는 속임수입니다.extglob
, , 입니다.find
또는 , 는는을를(으)입니다.grep
두 개의 파일 목록을 세트로 처리하고 다음을 사용하여 "확산"하는 것입니다.comm
다음을 참조하십시오
comm -23 <(ls) <(ls *Music*)
comm
보다 바람직합니다.diff
이겁니다.
이렇게 하면 세트 1, ㄴㄴ 1의 모든 요소가 반환됩니다.ls
세트 2에도 없습니다.ls *Music*
. 이렇게 하려면 두 세트가 정렬되어 있어야 합니다 이렇게 하려면 두 세트가 정렬되어 있어야 합니다.문제 없습니다.ls
그리고 지구본 확장도 있지만, 만약 '지구본 확장을 사용한다면 '지구본 확장'을 사용해요.find
, 꼭 , 을 불러주세요sort
요.
comm -23 <(find . | sort) <(find . | grep -i '.jpg' | sort)
잠재적으로 유용합니다.
아주 간단한 것도 쓸 수 있어요.for
loop.
for f in `find . -not -name "*Music*"`
do
cp $f /target/dir
done
에서는 bash의 대안으로 bash를 들 수 있습니다.shopt -s extglob
변수입니다.그게 더 나은 건 아니지만 기억하기가 더 쉬워요.
원본 포스터가 원하는 예를 들어 보겠습니다.
GLOBIGNORE="*techno*"; cp *Music* /only_good_music/
끝나면요unset GLOBIGNORE
수 있습니다rm *techno*
이겁니다.
개인적으로 선호하는 것은 grep 및 while 명령어를 사용하는 것입니다.이렇게 하면 강력하면서도 읽을 수 있는 스크립트를 작성할 수 있으므로 원하는 대로 정확하게 수행할 수 있습니다.또한 echo 명령을 사용하여 실제 작업을 수행하기 전에 시운전을 수행할 수 있습니다.예를 들어 다음과 같습니다.
ls | grep -v "Music" | while read filename
do
echo $filename
done
복사하게 될 파일을 인쇄합니다.목록이 올바른 경우 다음 단계는 다음과 같이 echo 명령을 copy 명령으로 간단히 대체합니다.
ls | grep -v "Music" | while read filename
do
cp "$filename" /target_directory
done
이를 위한 한 가지 솔루션은 find를 통해 찾을 수 있습니다.
$ mkdir foo bar
$ touch foo/a.txt foo/Music.txt
$ find foo -type f ! -name '*Music*' -exec cp {} bar \;
$ ls bar
a.txt
찾기에는 여러 가지 옵션이 있으며, 포함하거나 제외하는 항목에 대해 구체적으로 지정할 수 있습니다.
편집: 주석의 Adam은 이것이 재귀적인 것이라고 지적했습니다.find 옵션 mindepth 및 maxdepth를 사용하면 이를 제어하는 데 유용할 수 있습니다.
다음 작품들은 모두 열거되어 있습니다.*.txt
숫자로 시작하는 파일은 제외하고 현재 dir에 있습니다.
이 기능은 에서 작동합니다.bash
, , 입니다.dash
, , 입니다.zsh
포식스입니다.
for FILE in /some/dir/*.txt; do # for each *.txt file
case "${FILE##*/}" in # if file basename...
[0-9]*) continue ;; # starts with digit: skip
esac
## otherwise, do stuff with $FILE here
done
첫 번째 줄에 있는 문양입니다.
/some/dir/*.txt
이 원인이 됩니다.for
루프를 반복하여 에 있는 모든 파일에 대해 반복하십시오./some/dir
그 이름은 로 끝납니다..txt
요.- - - ? - - 、 the 、 the 、 the the 、 the 그 ? - - – – – – – – – ? - ? -?
${FILE##*/}
expression은 파일 이름에서 dir 이름 구성 요소를 제거합니다(여기서 dir name은 dir name으로 지정)./some/dir/
접미사를 기준으로 파일 이름만 제거하는 경우 파일 이름을 줄여서 사용할 수 있습니다.)$FILE
대신. (으)ㄹ 수 있다'라고 합니다.세 번째 줄에는 모든 파일이 일치합니다.
case
패턴 식식입니다.[0-9]*
) 행은 건너뜁니다 ).continue
다음 번 반복으로 .for
loop). – 여기에서 더 흥미로운 작업을 수행할 수 있습니다. 예를 들어, 루프를 사용하여 문자(a~z)로 시작하지 않는 모든 파일을 건너뛸 수 . – 여기에서 더 흥미로운 작업을 수행할 수 있습니다. 예를 들어, 문자(a~z)로 시작하지 않는 모든 파일을 건너뛸 수 있습니다.[!a-z]*
또는 여러 패턴을 사용하여 여러 종류의 파일 이름을 건너뛸 수 있습니다(예:[0-9]*|*.bak
둘 다 건너뛰기 위해서입니다..bak
숫자로 시작하지 않는 파일 및 파일입니다.
이것은 정확히 '음악'을 제외하고 할 수 있습니다.
cp -a ^'Music' /target
음악 같은 거 빼고 이것저것 다요?* 또는 *?음악입니다.
cp -a ^\*?'complete' /target
cp -a ^'complete'?\* /target
언급URL : https://stackoverflow.com/questions/216995/how-can-i-use-inverse-or-negative-wildcards-when-pattern-matching-in-a-unix-linu 입니다.
'programing' 카테고리의 다른 글
ASP에서 연결 문자열을 설정하는 중입니다.NET에서 SQL SERVERVER (0) | 2023.04.25 |
---|---|
운영자처럼요? (0) | 2023.04.25 |
bash의 if 블록에서 부울 변수를 평가하는 방법은 무엇입니까? (0) | 2023.04.25 |
Excel 한 열의 값이 다른 열의 값 범위에 있습니다. (0) | 2023.04.25 |
WPF DataGrid 유효성 검사 오류가 지워지지 않습니다. (0) | 2023.04.25 |