Grep은 여러 일치 항목에서 실패합니다.

Grep은 여러 일치 항목에서 실패합니다.

검색 패턴을 찾고 싶지만 고유한 일치 항목이 하나만 있는 경우에만 성공하고 일치하는 줄을 출력합니다. 두 줄이 일치하면 grep은 실패하거나 아무것도 인쇄하지 않습니다.

답변1

로는 이 작업을 수행할 수 없지만 grep단순히 일치하는 항목 수를 셀 수 있습니다. 어떤 쉘을 사용하고 있는지, 어떤 OS를 사용하고 있는지는 모르지만 grep다음은 이를 수행할 수 있는 bash 함수의 예입니다.

maxOne() (
    pattern="$1"
    file="$2"
    IFS=$'\n'
    set -f

    results=( $(grep -m2 -- "$pattern" "$file") )
    if [ "${#results[@]}" -eq 1 ]; then
        printf -- '%s\n' "${results[@]}"
        return 0
    else
        return 1
    fi
)

다음 줄을 파일에 추가하거나 ~/.bashrc실행 중인 bash 세션의 터미널에 붙여넣으면 다음을 수행할 수 있습니다.

maxOne foo file

foo에서 검색하려면 file. -m여기서 사용된 옵션(최대 결과)은 두 grep게임 후에 종료하는 효율성을 위한 것이며 모든 버전에서 지원되지 않으므로 grep오류가 발생하면 그냥 제거하세요. 이는 필수 사항이 아니며 작업 속도를 높여줄 뿐입니다.

중요한: 여러 줄 검색 문자열에서는 작동하지 않습니다. 지원 grep -z하는 경우 여러 줄 검색 문자열을 사용할 수 있습니다 grep. 여러 줄 검색 패턴을 처리할 수 있어야 한다면 다른 접근 방식이 필요합니다. 또한 이는 빈 줄과 일치하는 패턴(예 grep '^$' file: )에서는 작동하지 않습니다.스테판의 솔루션빈 줄은 처리되므로 이것이 문제라면 이것이 더 나은 선택이 될 것입니다. 나와 달리 그는 여러 파일을 처리할 수도 있는데 이는 좋은 보너스입니다.

답변2

다음을 수행할 수 있습니다.

unique_egrep() (
  export ERE="$1"; shift
  exec gawk -e '
    BEGIN               {ret = 1}
    BEGINFILE           {n = 0}
    $0 ~ ENVIRON["ERE"] {if (n++) nextfile; found = $0}
    ENDFILE             {if (n == 1) {print FILENAME":"found; ret = 0}}
    END                 {exit ret}' -E /dev/null "$@"
)

다른 unique_egrep pattern *.txt예시.

여기서 사용됨-e 'code' -E /dev/null(대체 'code') 스킬임의의 파일 경로를 처리하는 기능.

-e, -E및 모두 GNU 확장입니다 BEGINFILE( 현재는 다른 많은 구현에서도 볼 수 있음).ENDFILEnextfilenextfile

관련 정보