Linux awk grep 파일 1에서 파일 2로

Linux awk grep 파일 1에서 파일 2로

파일 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;

grepfile2의 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로 사용하므로 파일의 모든 줄은 ,... 따라서 일치시키려고 하면 다음과 같습니다.regexglobbinggrepregex

존재하다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 1CR 또는 ^M으로 끝나는 문자열이 검색됩니다. 이를 확인하는 가장 빠른 방법: cat -A 1. 각 줄 끝에 ^M이 표시되면 문제가 있는 것입니다.

관련 정보