source

grep를 사용하여 한 줄에 두 문자열을 일치시킵니다.

myloves 2023. 4. 19. 00:42

grep를 사용하여 한 줄에 두 문자열을 일치시킵니다.

는 용하려합합 i i i i i를 사용하려고 합니다.grep 2개의 다른 문자열을 포함하는 행을 대조합니다.다음을 시도했지만, 이것은 내가 원하는 것이 아닌 string1orstring2 중 하나를 포함하는 행과 일치합니다.

grep 'string1\|string2' filename

어떻게 요?grep의 문자열이 모두 포함된 행만요?

사용할 수 있습니다.

grep 'string1' filename | grep 'string2'

또는

grep 'string1.*string2\|string2.*string1' filename

이게 당신이 찾고 있던 거라고 생각해요.

grep -E "string1|string2" filename

내 생각에 그것은 다음과 같다.

grep 'string1.*string2\|string2.*string1' filename

둘 다 존재하는 경우에만 일치하며 둘 중 하나 또는 둘 다 일치하지 않습니다.

모든 단어가 포함된 파일을 임의의 순서로 검색하려면:

grep -ril \'action\' | xargs grep -il \'model\' | xargs grep -il \'view_type\'

번째 검색GREP')을 합니다.ri일치하는 파일 을 나열(l (1 용어'action'작은 따옴표 포함)가 파일의 모든 위치에 표시됩니다.

이후 GREP에서는 다른 용어를 검색하여 대소문자를 구분하지 않고 일치하는 파일을 나열합니다.

최종 파일 목록은 파일 내 임의의 순서로 이러한 용어를 포함하는 파일입니다.

「 」가 grep a -P된 ""의 " 옵션perl 를 할 수 있습니다.

grep -P '(?=.*string1)(?=.*string2)'

중복되는 문자열로 작업할 수 있는 장점이 있습니다. It's somewhat more straightforward using 사용법이 좀 더 간단합니다.perl as ~하듯이grep, 더 직접 지정하고 논리적으로 지정할 수 있기 때문입니다.로직과 로직을 보다 직접 지정할 수 있기 때문입니다.

perl -ne 'print if /string1/ && /string2/'

메서드는 -w만 빼고 거의 성공했습니다.

grep -w 'string1\|string2' filename

다음과 같은 작업을 수행할 수 있습니다.

(pattern1.*pattern2|pattern2.*pattern1)

|정규 표현에서 연산자는 의미나 다름없다.규 현 산 자 는 연 1 string 일 나2 string1 string치합즉하니가 will2 match either다 is to or string중표,또는 say식의또할 수 있습니다.다음과 같은 작업을 할 수 있습니다.

grep 'string1' filename | grep 'string2'

첫 번째 명령어의 결과를 두 번째 GREP로 파이핑합니다.그러면 두 줄 모두 일치하는 선만 표시됩니다.

perl, python, 복잡한 셸 스크립트를 제안하는 것처럼 간단한 awk 접근방식을 제시하겠습니다.

awk '/string1/ && /string2/' filename

인정된 답변에 대한 코멘트를 보면: 아니요, 이것은 여러 줄을 사용할 수 없습니다. 하지만 질문의 작성자가 요구한 것도 아닙니다.

이 경우 grep을 사용하지 말고 awk를 사용하십시오.GREP에서 2개의 regexps R1과 R2를 일치시키려면 다음과 같이 생각할 수 있습니다.

grep 'R1.*R2|R2.*R1'

한편, 다음과 같습니다.

awk '/R1/ && /R2/'

만약에 '만일'이R2겹치거나 겹치거나 겹치거나 겹치는 부분집합이다.R1grep awk awk 。 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 요.the그리고.heat:

$ echo 'theatre' | grep 'the.*heat|heat.*the'
$ echo 'theatre' | awk '/the/ && /heat/'
theatre

여기에는 2개의 GREP와 파이프를 사용해야 합니다.

$ echo 'theatre' | grep 'the' | grep 'heat'
theatre

물론 실제로 그것들을 분리할 필요가 있다면, 항상 grep에서 사용한 것과 같은 regexp를 awk로 쓸 수 있습니다.또한 가능한 모든 시퀀스에서 regexps를 반복하지 않아도 되는 대체 awk 솔루션이 있습니다.

한편, 솔루션을 3개의 regexps R1, R2, 및 R3에 일치하도록 확장하고 싶다면 어떻게 해야 할까요?GREP에서는 다음과 같은 선택지를 선택할 수 없습니다.

grep 'R1.*R2.*R3|R1.*R3.*R2|R2.*R1.*R3|R2.*R3.*R1|R3.*R1.*R2|R3.*R2.*R1' file
grep R1 file | grep R2 | grep R3

간결하고 명확하며 심플하고 효율적입니다.

awk '/R1/ && /R2/ && /R3/'

regexps R1과 R2가 아닌 리터럴 문자열 S1과 S2를 실제로 대조하는 경우는 어떻게 해야 할까요?GREP에 콜을 1개만으로 실행할 수 없습니다.GREP에 콜을 발신하기 전에 모든 RE 메타차를 이스케이프하기 위한 코드를 작성해야 합니다.

S1=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< 'R1')
S2=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< 'R2')
grep 'S1.*S2|S2.*S1'

또는 2개의 greps와 파이프 1개를 다시 사용한다.

grep -F 'S1' file | grep -F 'S2'

awk에서는 regexp 연산자가 아닌 문자열 연산자를 사용할 뿐이지만, 이것도 역시 선택지가 아닙니다.

awk 'index($0,S1) && index($0.S2)'

한 줄이 아니라 한 문단에서 두 개의 정규식을 일치시키고 싶다면 어떻게 해야 할까요?GREP로 할 수 없고, awk로 할 수 없습니다.

awk -v RS='' '/R1/ && /R2/'

전체 파일에 걸쳐서 보는 건 어때?다시 grep와 trivial in awk에서는 실행할 수 없습니다(이번에는 conciency를 위해 멀티 문자 RS에 GNU awk를 사용하고 있습니다만, 어느 awk에서도 그다지 많은 코드를 사용할 수 없습니다.또, RS가 같은 처리를 하기 위해서 입력에 포함되지 않는 control-char를 선택할 수도 있습니다).

awk -v RS='^$' '/R1/ && /R2/'

따라서 한 줄, 단락 또는 파일에서 여러 개의 regexps 또는 문자열을 찾으려면 grep를 사용하지 마십시오.

git grep

여러 패턴을 사용한 구문을 다음에 나타냅니다.

git grep --all-match --no-index -l -e string1 -e string2 -e string3 file

패턴을 다음과 같은 부울식과 조합할 수도 있습니다.--and,--or그리고.--not.

확인.man git-grep도움을 청합니다.


--all-match여러 패턴 식을 지정할 때 이 플래그는 모든 패턴 식과 일치하는 행이 있는 파일로 일치를 제한하도록 지정합니다.

--no-index Git에 의해 관리되지 않는 현재 디렉토리의 파일을 검색합니다.

-l/--files-with-matches/--name-only파일 이름만 표시합니다.

-e다음 파라미터는 패턴입니다.기본적으로는 기본 regexp를 사용합니다.

기타 고려해야 할 사항:

--threads사용할 GREP 워커 스레드 수

-q/--quiet/--silent일치하는 행을 출력하지 마십시오.일치가 있을 경우 상태 0으로 종료합니다.

패턴 유형을 변경하려면 다음을 사용할 수도 있습니다.-G/--basic-regexp(디폴트),-F/--fixed-strings,-E/--extended-regexp,-P/--perl-regexp,-f file, 기타.

관련:

OR 동작에 대해서는, 다음을 참조해 주세요.

6개의 공백으로 시작하여 다음으로 끝나는 행을 찾았습니다.

 cat my_file.txt | grep
 -e '^      .*(\.c$|\.cpp$|\.h$|\.log$|\.out$)' # .c or .cpp or .h or .log or .out
 -e '^      .*[0-9]\{5,9\}$' # numers between 5 and 9 digist
 > nolog.txt

파일 테스트 파일에서 여러 단어 수를 찾아야 한다고 가정해 보겠습니다.두 가지 방법이 있다

1) regex 매칭 패턴과 함께 grep 명령어를 사용한다.

grep -c '\<\(DOG\|CAT\)\>' testfile

2) egrep 명령어 사용

egrep -c 'DOG|CAT' testfile 

egrep을 사용하면 표현식에 대해 걱정할 필요가 없으며 파이프 구분자로 단어를 구분하기만 하면 됩니다.

grep ‘string1\|string2’ FILENAME 

GNU GREP 버전 3.1

GREP할 문자열을 파일에 저장합니다.

echo who    > find.txt
echo Roger >> find.txt
echo [44][0-9]{9,} >> find.txt

그런 다음 -f를 사용하여 검색합니다.

grep -f find.txt BIG_FILE_TO_SEARCH.txt 
grep '(string1.*string2 | string2.*string1)' filename

임의의 순서로 string1과 string2의 행을 가져옵니다.

여러 줄의 일치:

echo -e "test1\ntest2\ntest3" |tr -d '\n' |grep "test1.*test3"

또는

echo -e "test1\ntest5\ntest3" >tst.txt
cat tst.txt |tr -d '\n' |grep "test1.*test3\|test3.*test1"

줄바꿈 캐릭터를 삭제하기만 하면 됩니다!

grep음음음같 뭇매하다

$ grep 'string1' file | grep 'string2'

저는 종종 당신과 같은 문제에 부딪히곤 하는데, 단지 대본 한 편을 썼을 뿐이에요.

function m() { # m means 'multi pattern grep'

    function _usage() {
    echo "usage: COMMAND [-inH] -p<pattern1> -p<pattern2> <filename>"
    echo "-i : ignore case"
    echo "-n : show line number"
    echo "-H : show filename"
    echo "-h : show header"
    echo "-p : specify pattern"
    }

    declare -a patterns
    # it is important to declare OPTIND as local
    local ignorecase_flag  filename linum header_flag colon result OPTIND

    while getopts "iHhnp:" opt; do
    case $opt in
        i)
        ignorecase_flag=true ;;
        H)
        filename="FILENAME," ;;
        n)
        linum="NR," ;;
        p)
        patterns+=( "$OPTARG" ) ;;
        h)
        header_flag=true ;;
        \?)
        _usage
        return ;;
    esac
    done

    if [[ -n $filename || -n $linum ]]; then
    colon="\":\","
    fi

    shift $(( $OPTIND - 1 ))

    if [[ $ignorecase_flag == true ]]; then
    for s in "${patterns[@]}"; do
            result+=" && s~/${s,,}/"
    done
    result=${result# && }
    result="{s=tolower(\$0)} $result"
    else
    for s in "${patterns[@]}"; do
            result="$result && /$s/"
    done
    result=${result# && }
    fi

    result+=" { print "$filename$linum$colon"\$0 }"

    if [[ ! -t 0 ]]; then       # pipe case
    cat - | awk "${result}"
    else
    for f in "$@"; do
        [[ $header_flag == true ]] && echo "########## $f ##########"
        awk "${result}" $f
    done
    fi
}

사용방법:

echo "a b c" | m -p A 
echo "a b c" | m -i -p A # a b c

괜찮으시다면 .bashrc에 넣으셔도 됩니다.

grep -i -w 'string1\|string2' filename

이 방법은 정확한 단어 일치 및 대소문자를 구분하지 않는 단어에 대해 작동하며 -i가 사용됩니다.

하면, 그 을 넣습니다.grep★★★★★★★★★★★★★★★★★★:

$ grep -E "string1(?.*)string2" file

의 행이 되어 있는 는, 과 같습니다.Dockerfile:

FROM python:3.8 as build-python
FROM python:3.8-slim

하려면 , 다음의 순서를 실행합니다.FROM python ★★★★★★★★★★★★★★★★★」as build-python뭇매를 맞다

$ grep -E "FROM python:(?.*) as build-python" Dockerfile

출력에는 두 문자열이 모두 포함된 행만 표시됩니다.

FROM python:3.8 as build-python

git을 초기화하여 브랜치에 추가하면 git grep을 사용하는 것이 좋습니다.이는 매우 빠르고 디렉토리 전체를 검색할 수 있기 때문입니다.

git grep 'string1.*string2.*string3'

, 두 개의 검색String 할 수 있는 은 「」뿐입니다.string1 ★★★★★★★★★★★★★★★★★」string2

grep -E 'string1.*string2|string2.*string1' filename | grep -E 'string1|string2'
  • 또는
grep 'string1.*string2\|string2.*string1' filename | grep -E 'string1\|string2'

두 문자열을 모두 grep하는 훨씬 간단한 명령어:

(cat file | grep 'phrase_1') && (cat file | grep 'phrase_2')

ripgrep

다음은 를 사용하는 예를 제시하겠습니다.

rg -N '(?P<p1>.*string1.*)(?P<p2>.*string2.*)' file.txt

유한 오토마타, SIMD 및 공격적인 리터럴 최적화를 사용하여 매우 빠르게 검색을 수행하는 Rust의 regex 엔진을 기반으로 구축되었기 때문에 가장 빠른 그리핑 도구 중 하나입니다.

특히 대용량 데이터를 사용할 때 사용합니다.

GH-875 에 있는 관련 기능의 요구도 참조해 주세요.

언급URL : https://stackoverflow.com/questions/4487328/match-two-strings-in-one-line-with-grep