'grep -c'를 접는 방법*.h *.cpp'를 단일 카운트로 변환하시겠습니까?

'grep -c'를 접는 방법*.h *.cpp'를 단일 카운트로 변환하시겠습니까?

NDEBUGPosix 어설션 종속성이 존재하지 않는지 확인하기 위해 C++ 코드에 자체 테스트를 추가하고 있습니다 (아래 뒷이야기). 첫 번째 테스트에서는 <assert.h>다음의 합계를 찾습니다 <cassert>.

FAILED=0
COUNT=$($EGREP -c '(assert.h|cassert)' *.h *.cpp)
if [[ "$COUNT" -ne "0" ]]; then
    FAILED=1
    echo "Found Posix assert headers" | tee -a "$TEST_RESULTS"
fi

생산:

************************************
Testing: No Posix assert

./cryptest.sh: line 1130: [[: 3way: value too great for base (error token is "3way")
...

디버깅하면 다음과 같이 표시됩니다.

bash -x ./cryptest.sh
...

++ egrep -c '(assert.h|cassert)' 3way.h adler32.h aes.h ...
+ COUNT='3way.h:0
adler32.h:0
aes.h:0
...

따라서 각 파일에는 자체 줄과 개수가 있습니다.

이것grep매뉴얼 페이지진술은 다음과 같습니다. 여러 줄 출력에 대해서는 논의하지 않습니다.

-c, --count
    Only a count of selected lines is written to standard output.

이 행동은 다음과 관련이 있는 것 같습니다.출력 제어(맨 페이지 구성) 및 -l, --files-with-matches. -L, --files-without-match비슷한 오류가 발생합니다.

제 질문은 결과를 어떻게 grep하나로 합칠 수 있느냐는 것입니다.

아니면 grep과 egrep이 해당 작업에 적합한 도구인지 물어봐야 할까요? grep과 egrep이 올바른 도구가 아닌 경우 무엇을 사용해야 합니까?


이는 우리가 지원하는 모든 플랫폼에서 실행될 수 있는 Bash 쉘 스크립트입니다. 각 플랫폼에는 BSD, Linux, OS X, Solaris 및 Unix(Android 및 iOS와 같은 모든 모바일 버전도 포함)가 포함됩니다. 우리는 grep다음 과 같은 필요한 도구를 얻기 위해 열심히 노력해야 합니다 egrep.

GREP=grep
EGREP=egrep
SED=sed
AWK=awk
DISASS=objdump
DISASSARGS=("--disassemble")
...

# Fixup
if [[ "$IS_SOLARIS" -ne "0" ]]; then
    IS_X64=$(isainfo 2>/dev/null | "$GREP" -i -c "amd64")
    if [[ "$IS_X64" -ne "0" ]]; then
        IS_X86=0
    fi

    # Need something more powerful than the non-Posix versions
    if [[ (-e "/usr/gnu/bin/grep") ]]; then
        GREP=/usr/gnu/bin/grep;
    fi
    if [[ (-e "/usr/gnu/bin/egrep") ]]; then
        EGREP=/usr/gnu/bin/egrep;
    fi
    if [[ (-e "/usr/gnu/bin/sed") ]]; then
        SED=/usr/gnu/bin/sed;
    fi
    if [[ (-e "/usr/gnu/bin/awk") ]]; then
        AWK=/usr/gnu/bin/awk;
    else
        AWK=nawk;
    fi

    DISASS=dis
    DISASSARGS=()
fi

...

배경 이야기

우리 프로젝트는 최근에CVE-2016-7420사용자는 Autotools 및 CMake와 같은 다른 도구를 사용하여 프로젝트를 빌드하기 때문입니다. CVE는 -DNDEBUG릴리스/프로덕션 빌드 생략의 직접적인 결과 입니다 . 다른 도구는 우리와 다르게 구성되어 있으며 사용자에게 (1) 다른 빌드 도구를 사용할 수 없거나 (2) 사용자에게 알리지 않습니다.~ 해야 하다-DNDEBUG릴리스/프로덕션을 정의합니다 .

우리의구제책NDEBUG문서에서 "단순히 릴리스/프로덕션을 정의"하는 것보다 훨씬 더 깊습니다. 우리는NDEBUGPosix에 대한 모든 종속성을 제거합니다.assert따라서 사람들이 실수로 구성에 들어갈 수 없습니다. 또한 사용자는 DEBUG정의하여 디버그 구성을 요청 해야 합니다 _DEBUG. 그렇지 않으면 릴리스 구성을 받게 됩니다.

후자 assertSIGART일반적으로 릴리스 빌드에서 성가신 일이지만 디버그 빌드에서는 양성으로 간주되고 당연한 것으로 간주되지만 우리는 다음을 관찰했습니다.

  • 우리는 안전한 도서관입니다(민감한 정보를 처리합니다)
  • 실패한 어설션은 중요한 정보를 파일 시스템(핵심 파일 및 충돌 보고서)으로 전달합니다.
  • 실패한 어설션은 Apple(CrashReporter), Apport(Ubuntu), Microsoft(Windows Error Reporting) 등과 같은 플랫폼 공급업체에 중요한 정보를 유출합니다.
  • Apple, Google, Microsoft 등의 기업은 정부와 협력하여 민감한 정보를 수집합니다.

답변1

참고: 다음은 의 GNU 구현을 기반으로 grep하지만 귀하의 경우에도 작동할 것이라고 생각합니다.

GNU grep매뉴얼에 명시된 바와 같이 (강조)

grep searches the named input FILEs for lines containing a match to the
given PATTERN.  If no files are specified, or if the file “-” is given,
grep  searches  standard  input.   By default, grep prints the matching
lines.

반품,

-c, --count
       Suppress  normal output; instead print a count of matching lines
       **for each input file**.  With the -v,  --invert-match  option  (see
       below), count non-matching lines.

(기본 동작은 해당 출력에서 ​​파일 이름 앞에 접두사를 붙이는 것입니다. 하지만 -h이 옵션을 사용하면 이를 억제할 수 있습니다.)

대상 파일을 단일 입력 스트림에 연결하고 다음으로 파이프하여 grep두 동작을 모두 재정의하고 접두사 없이 단일 개수를 얻을 수 있어야 합니다 .

COUNT=$(cat *.h *.cpp | $EGREP -c '(assert.h|cassert)')

IMHO 이것은 다음과 같은 자격이 있습니다.효과가있다고양이를 사용하십시오. 아마도 당신이 권장하는 것은고양이의 쓸모없는 사용

답변2

스틸 드라이버의 답변귀하의 질문 제목을 읽었을 때 (do)라는 생각이 가장 먼저 들었습니다. 하지만 스크립트 조각에서 0과 비교하는 것 외에는 개수를 사용하지 않는 것으로 나타났습니다. 즉, "몇 개가 있습니까?"라고 묻고 있는 것입니다. 다음을 사용하는 것을 고려해보세요:cat files | grep -c <token>-q

if "$EGREP" -q -- 'assert\.h|cassert' *.h *.cpp
then
    FAILED=1
    echo "Found Posix assert headers" …
fi

노트:

  • "$EGREP"타당한 이유가 없고 수행 중인 작업을 확실히 알고 있지 않는 한 항상 쉘 변수 참조(예: )를 인용해야 합니다 . 정의했다면 EGREP=grep -e이는 quote 를 사용하지 않는 타당한 이유가 될 것입니다 $EGREP. 그러나 다음을 참조하십시오.이 답변도착하다bash/POSIX 쉘에서 변수를 인용하는 것을 잊어버리는 보안 위험.
  • -q(또는 동등하게 --quietor --silent)는 "조용함. 표준 출력에 아무 것도 쓰지 마십시오. 일치하는 항목이 발견되면 오류가 감지되더라도 상태 0으로 즉시 종료하십시오."를 의미합니다. 이는 필요한 기능적 동작( 즉, Steeldriver의 답변과 동일한 기능적 동작이지만 grep일치 항목이 발견되면 종료하고 모든 파일을 읽을 필요가 없다는 성능 이점이 있습니다. 
  • 로 시작하는 파일 이름이 옵션 문자열로 해석되는 것을 --방지하려면 명령의 옵션과 해당 인수 사이에 배치하는 것이 좋습니다 .-
  • 전체 정규식을 괄호로 묶을 필요는 없습니다.
  • grep 'assert.h'assert h, assert,h, 등과 일치합니다 assert3h. assertph당신이 상관하지 않는다면 그것은 당신에게 달려 있습니다. 단지 일치시키려면 assert.hgrep for assert\.h.

관련 정보