파일 1에 정규 표현식이 있습니다.
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8802.*.*.*.*84231655.*
다음과 같은 레코드를 포함하는 다른 파일이 많이 있습니다.
0081347504;03.05.2019 10:51;000010;000000001000126289;8601;Kontaktschreiben;;;;;00000000000901326394;
0081349117;03.05.2019 10:51;000020;000000002000044721;8906;Termin vereinbaren;;;07.05.2019;10:00;14:00;00000000000901332422;
0081349117;03.05.2019 10:51;000030;000000002000044722;8906;Termin vereinbaren;;;07.05.2019;10:00;14:00;00000000000901332423;
0081351563;03.05.2019 10:52;000010;000000001000116607;8906;Termin vereinbaren;;;06.05.2019;13:00;18:00;00000000000901332339;
grep
file2의 file1에 있는 모든 레코드를 원합니다 .
나는 그것을 시도했지만 grep -Ff file 1 ./*
작동하지 않습니다.
답변1
약간의 깔끔함은 결코 나쁠 것이 없습니다.
우선 헷갈리실 수도 있을 것 같아요regexes
그리고Globbing
; 그리고 어떤 행에 관계없이 동일한 행을 두 번 이상 반복할 필요가 없습니다(아마도 해석할 행이 많다는 것을 나타내려고 regexes
하지만 각 행을 고유하게 만들기에는 너무 게으르다). .. 하지만 확실히 하기 위해). 그래서 이거:
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8912.*.*.*.*81415444.*
.*8802.*.*.*.*84231655.*
대신 이것을 사용할 수 있습니다:
.*8912.*.*.*.*81415444.*
.*8802.*.*.*.*84231655.*
알았어... 이제 어떡하지? ...음, 모든 줄을 (가 아닌 ) grep
로 사용하므로 파일의 모든 줄은 ,... 따라서 일치시키려고 하면 다음과 같습니다.regex
globbing
grep
regex
존재하다8912
존재하다81415444
존재하다
어디존재하다대표하다:아무것
이것:
.*8912.*81415444.*
충분할 것입니다.
그런 다음 파일에서 사용하십시오 regex
.
.*8912.*81415444.*
.*8802.*84231655.*
그러나 일치시키려는 경우:
가리키다 존재하다8912가리키다 존재하다 가리키다 존재하다 가리키다 존재하다 가리키다 존재하다81415444가리키다 존재하다
어디존재하다대표하다:아무것그리고가리키다대표하다텍스트 포인트, 이는 regex
잘못된 것입니다. 왜냐하면 에서 regexes
점이 a이기 때문입니다.meta-character
...매번 탈출해야 해텍스트 포인트backslash
> 를 사용 \
하면 정규식은 다음과 같아야 합니다.
\..*8912\..*\..*\..*\..*81415444\..*
그런 다음 파일에서 사용하십시오 regex
.
\..*8912\..*\..*\..*\..*81415444\..*
\..*8802\..*\..*\..*\..*84231655\..*
또는 다음 과 egrep
동일하게 사용할 수 있습니다 .grep --extended-regexp
확장 정규식, 정규식을 단순화중복 제한, 다음과 같이 더 간결한 방식으로 위와 똑같은 작업을 수행합니다.
\..*8912(\..*){4}81415444\..*
\..*8802(\..*){4}84231655\..*
(정규식을 확장하지 않고도 비슷한 작업을 수행할 수 있지만 다음과 같이 더 많은 백슬래시를 사용해야 합니다 \..*8912\(\..*\)\{4\}81415444\..*
. :)
이제 두 개의 디렉터리가 포함된 디렉터리에 있다고 상상해 보세요. 하나는정규식(하나는 정규식 파일 포함)이고 다른 하나는샘플 파일(정규식과 일치시키려는 파일이 포함된 파일)...
그런 다음 다음 명령을 사용하여 목표를 달성할 수 있습니다.
grep --colour -f ./regex/YOUR_REGEX_FILENAME ./sample_files/*
아래와 같이 일부 출력이 표시됩니다.
./sample_files/sample_file2:0088027504;03.05.2019 10:51;000010;000000008423165589;8601;Kontaktschreiben;;;;;00000000000901326394;
./sample_files/sample_file7:0089128117;03.05.2019 10:51;000030;000000002814154447;8906;Termin vereinbaren;;;07.05.2019;10:00;14:00;00000000000901332423;
당신은 이렇게 말할 수 있습니다: 왜 두 개의 별도 디렉토리가 있습니까? 글쎄, 이것이 꼭 필요한 것은 아니지만 문제는 예제 파일과 정규식 파일이 동일한 디렉터리에 있고 다음과 같은 명령을 사용하는 경우입니다.
grep -f file_1 ./*
이는 ./*
와일드카드를 사용하며 정규식 파일을 포함하여 현재 디렉터리의 모든 파일과 일치합니다.
이 경우 예를 들어 정규 표현식 파일에 고유한 확장명을 추가한 .regex
다음 이 파일의 글로빙 패턴을 변경하면 됩니다. ./!(*.regex)
...이 글로빙은 ..로 시작하는 이름을 제외합니다. 파일이 .regex
있으면 명령은 다음과 같습니다.
grep -f file_1.regex ./!(*.regex)
마지막으로 주의 사항: 이스케이프하지 않고는 쉘에서 공백이 있는 이름을 사용할 수 없습니다. 각 공백을 백슬래시로 이스케이프하거나 전체 이름을 따옴표로 묶을 수 있습니다.
답변2
matsib.dev의 탁월한 답변 외에도 다음이 포함됩니다.
-F 플래그가 확실합니까? 정규식을 끄고 grep이 고정 문자열을 검색하도록 합니다. 따라서 .*
점과 별표가 포함된 줄만 적중됩니다.
확인해야 할 또 다른 사항은 파일의 내용입니다 1
. dos와 같은 줄 끝이 있는 경우(즉, 줄이 단일 LF가 아닌 CRLF로 끝나는 경우) grep -f 1
CR 또는 ^M으로 끝나는 문자열이 검색됩니다. 이를 확인하는 가장 빠른 방법: cat -A 1
. 각 줄 끝에 ^M이 표시되면 문제가 있는 것입니다.