여러 옵션에 그룹화 괄호는 언제 필요합니까?

여러 옵션에 그룹화 괄호는 언제 필요합니까?

나는 사용 find하고 grep명령합니다.

여러 옵션을 연결하기 위해 플래그와 함께 "or"를 사용해야 하는 경우와 그룹화 괄호를 사용해야 하는 경우 및 그룹화 괄호를 사용하지 않는 경우에 대해 -o매우 혼란스럽습니다 .

사용할 때 find그룹화 괄호가 필요한 것으로 보입니다.

find $fdir ( -name *.texi -o -name *.org )

를 사용할 때 grep그룹화 괄호를 사용하지 마십시오.

grep --include "*.texi" --exclude "*.org"

답변1

괄호를 포함한 대부분의 프로그램은 grep괄호를 매개변수로 구체적으로 처리하지 않습니다. 이렇게 하면:

grep "(" --include "*.texi" --exclude "*.org" ")"

grep(첫 번째 항목을 검색할 패턴으로 처리 하고 마지막 항목을 )파일 이름으로 처리합니다. (*)foo 마치 똑같은 것처럼 bar. 따라서 옵션을 로 그룹화할 수 없습니다 grep.


하지만 문제는 다음과 같습니다. -name, -type-o(그렇지 않습니다.옵션도착하다 find. 심볼릭 링크 처리에 영향을 미치는 -P/ -H/ 와 같은 일부 옵션이 필요 -L하지만 이는 옵션이 아닙니다. 대신 (**) 에 특정한 검색 표현식의 일부입니다 find.

강조하다표현하다거기. find표현식을 제공하면 ( -name *.texi -o -name *.org )C와 유사한 표현식에 더 가깝습니다.

( patternmatch(filename, "*.texi") || patternmatch(filename, "*.texi") )

그 무엇보다 더. 그리고 find보이는 모든 파일에 대해 해당 표현식을 평가합니다. 예를 들어 다음과 같은 경우가 있습니다.

( -name *.texi -o -name *.org ) -printf something

괄호가 없기 때문에 괄호가 필요합니다.

-name *.texi -o -name *.org -printf something

동일할 것이다

-name *.texi -o -name *.org -a -printf something

암묵적인 내용이 있기 때문에그리고원자 사이의 관계가 주어지지 않는 한 -o표현은 다음과 같습니다.

patternmatch(...) || patternmatch(...) && printf(...)

그리고그리고가동률또는연산은 거의 모든 프로그래밍 언어에서와 동일하게 작동하며 곱셈은 덧셈보다 더 밀접하게 연결되어 있습니다. 그리고 find임의의 표현을 지원하기 때문에 자신이 원하는 것이 무엇인지 알 방법이 없습니다. (***) 따라서 이 경우에는 괄호가 없으면 원하는대로 작동하지 않습니다.


-print다른 사람들이 지적했듯이, find 표현식에 "action"( 등 ) 이 없으면 -exec기본적으로 일치하는 파일 이름을 인쇄하고 암시적으로 표현식 주위에 괄호를 넣기 때문에 당신이 가지고 있는 명령에는 괄호가 필요하지 않습니다.

그래서,

find "$fdir" -name "*.texi" -o -name "*.org"

처럼 행동하다

find "$fdir" \( -name "*.texi" -o -name "*.org" \) -print

그러나 명시적으로 입력하는 경우 -print올바른 처리 순서를 얻으려면 명시적으로 괄호도 입력해야 합니다. 바라보다:여러 개의 '-name' 및 '-exec'가 있는 'find'는 마지막으로 나타나는 '-name'만 실행합니다.


돌아가기 grep: grep괄호 없이, 표현식을 처리하지 않으므로 필요하지 않습니다. 중첩이나 연산자 개념이 없습니다.그리고그리고또는일반적으로 말하면. 대신, 하드 코딩된 동작을 갖습니다. --include와 의 경우에는 --exclude포함 규칙과 제외 규칙을 모두 만족시키려고 하는 것 같습니다. (또는 최소한 하나의 --include규칙은 있지만 단일 --exclude규칙은 아닙니다.) 그러나 여러 검색 패턴의 경우 하나를 일치시키는 것으로 충분합니다.또는다른. 둘 다 정적 규칙입니다. 어떤 패턴이 일치해야 하는지를 나타내는 더 복잡한 표현을 제공할 수는 없습니다.


(* GNU grep은 중간 항목을 옵션으로 처리하며, 옵션 처리가 옵션이 아닌 인수 이전에 중지되므로 다른 구현에서도 이를 파일 이름으로 처리할 수 있습니다. 또한 괄호를 인용하거나 이스케이프 처리하여 이를 방지해야 합니다.껍데기;그들이 하는 일과는 아무런 관련이 없습니다 grep. )

grep(** 다시 말하지만 옵션이 아닌 첫 번째 인수가 모드이고 나머지 인수만 파일 이름이거나 마지막 인수가 mv대상이고 다른 인수가 이동할 파일인 경우 에만 해당되며 git해당 항목 에만 해당됩니다. 다른 작업을 수행하는 도구이므로 명령줄 인수를 다르게 사용해야 합니다).

(*** 누군가가 평가식은 다음과 같다고 말한 적이 있습니다.중요한 것 find하다. 즉, 인쇄할 파일 이름을 찾지 않고 파일 트리를 살펴봅니다.계산식그들 안에. 외부 명령을 인쇄하고 실행하는 것은 단지 부작용일 뿐입니다. )

답변2

일반적인 규칙은 없습니다. 주어진 명령이 인수로 인식하는 것은 명령에 따라 다릅니다.grep인수를 그룹화하는 데 괄호를 사용하지 마십시오.

~을 위한find, 우선순위가 다음인 경우에만그리고비교적또는재정의해야 합니다. 이는 수학에서 괄호를 사용하는 것과 유사합니다. 귀하의 예에서는 기본 우선 순위가 표현식에 동일한 전반적인 의미를 부여하기 때문에 필요하지 않습니다.

find "$fdir" -name '*.texi' -o -name '*.org'

답변3

프로그램이 명령줄 인수를 해석하는 방법에 대한 표준이 없기 때문에 혼란이 발생합니다. 일반적으로 매개변수의 해석은 프로그래머의 몫입니다.GNU 코딩 표준제안된 프로그램 사용 getopt()getopt_long()기능(~GNU C 라이브러리) 이 목적을 위해.

이는 연산자 우선순위를 정의하는 괄호의 해석이 find호출 쉘에서 사용되는 함수가 아니라 함수의 함수라는 것을 의미합니다 find. "간단한" 프로그래머는 grep옵션 구문 분석 알고리즘을 이런 방식으로 구현하지 않으므로 grep애초에 표기법을 이해하지 못할 것입니다.

하지만 참고하세요괄호는 셸에서 특별한 의미를 갖습니다. 괄호는 포함된 내용이 실행될 명령임을 나타냅니다.서브쉘에서. 따라서 게시한 명령은 실제로 작동하지 않아야 합니다. @terdon이 언급했듯이 먼저 \( ... \)쉘이 이를 전달하려면 괄호(예: )를 이스케이프해야 합니다 .find

답변4

매뉴얼에는 find도움이 될 수 있는 괄호 사용 방법에 대한 몇 가지 통찰력이 있다고 생각합니다.

2.12 원색과 연산자의 결합

연산자는 테스트 및 작업을 기반으로 복잡한 표현식을 작성합니다. 연산자는 우선순위 내림차순으로 나열됩니다.

( expr )

강제 우선순위. 사실 이라면 사실입니다 expr.

! expr
-not expr

거짓이면 참입니다 expr. 일부 쉘에서는 '!'를 인용하여 쉘 해석으로부터 보호해야 합니다.

expr1 expr2 expr1 -a
expr2 expr1 -and expr2

거짓인 경우 expr2평가가 수행되지 않습니다.expr1

expr1 -o expr2 expr1 -or expr2

또는 사실이라면 expr2평가하지 마세요.expr1

expr1 , expr2

둘 다 나열 expr1하고 expr2항상 평가됩니다. 사실 이라면 사실입니다 expr2. 값이 expr1삭제됩니다. 이 연산자를 사용하면 다른 작업의 성공에 의존하지 않고 단일 패스에서 여러 개의 독립적인 작업을 수행할 수 있습니다. 파일을 터치하거나 삭제하는 등의 부작용이 발생할 수 있거나 expr2`가 사용될 수 있으므로 두 작업이 expr1항상 expr2 완전히 독립적인 것은 아닙니다.expr1-prune’ which would also affect

find각 파일 이름에 루트가 있는 디렉토리 트리는 결과가 알려질 때까지(왼쪽의 경우 false -and, 의 경우 true -or) 표현식을 왼쪽에서 오른쪽으로 평가하여 우선순위 규칙에 따라 검색되며, 그 시점에서 find는 다음 파일 이름으로 진행됩니다.

관련 정보