>

모두. 나는

file 1.log: text1 value11 text text text text2 value12 text

file 2.log: text1 value21 text text text text2 value22 text

원합니다 :

value11;value12 value21;value22

현재로서는 분리 된 파일에 값을 grep하고 나중에 다른 파일에 붙여 넣습니다. 그러나 모든 파일을 두 번 이상 읽어야하므로 grep을 사용하여 모든 데이터를 추출하려고합니다. 고양이 한 마리 | grep line이지만 예상 한 결과가 아닙니다.

사용합니다 : cat *.log | grep -oP "(?<=text1 ).*?(?= )|(?<=text2 ).*?(?= )" | tr '\n' '; '

또는

cat *.log | grep -oP "(?<=text1 ).*?(?= )|(?<=text2 ).*?(?= )" | xargs

그러나 각 경우에 나옵니다 :

value11;value12;value21;value22

value11 value12 value21 value22

정말 감사합니다.


  • 답변 # 1

    시도 :

    $ awk -v RS='[[:space:]]+' '$0=="text1" || $0=="text2"{getline; printf "%s%s",sep,$0; sep=";"} ENDFILE{if(sep)print""; sep=""}' *.log
    value11;value12
    value21;value22
    
    

    명령을 선호하는 사람들은 여러 줄로 퍼져 있습니다 :

    awk -v RS='[[:space:]]+' '
        $0=="text1" || $0=="text2" {
            getline
            printf "%s%s",sep,$0
            sep=";"
         }
         ENDFILE {
            if(sep)print""
            sep=""
         }' *.log
    
    
    작동 원리

    -v RS='[[:space:]]+'

    이렇게하면 일련의 공백 (줄 바꿈, 공백, 탭 등)을 레코드 구분 기호로 취급 할 수 있습니다.

    $0=="text1" || $0=="text2"{getline; printf "%s%s",sep,$0; sep=";"}

    이것은 awk에게 text1 or 와 일치하는 파일 레코드를 찾도록 지시합니다. text2`. 해당 레코드 및 해당 레코드의 경우 중괄호 안의 명령 만 실행됩니다. 이러한 명령은 다음과 같습니다.

    getline  awk에게 다음 레코드를 읽도록 지시합니다.

    printf "%s%s",sep,$0  awk에게 변수 sep 를 인쇄하도록 지시합니다.  그 뒤에 기록에 나오는 단어가옵니다.

    첫 번째 일치를 인쇄 한 후 sep=";" 명령  awk에게 sep 의 값을 설정하도록 지시하는  세미콜론으로.

    각 파일을 시작할 때 sep  비었다. 이는 파일에서 첫 번째로 일치하는 항목 앞에 구분 기호가없는 것으로 인쇄됨을 의미합니다. 동일한 파일의 모든 후속 일치에는 ; 가 있습니다.  그들을 분리하기 위해.

    ENDFILE{if(sep)print""; sep=""}

    각 파일의 끝에 도달하면 sep 인 경우 줄 바꿈을 인쇄합니다.  비어 있지 않은 다음 sep 를 설정합니다.  빈 문자열로 돌아갑니다.

    대체 : 첫 번째 단어가 숫자로 끝나면 두 번째 단어 인쇄

    질문에 대한 대안 적 해석 (해트 팁 : David C. Rankin)에서는 첫 번째 단어가 숫자로 끝나는 행에 두 번째 단어를 인쇄하려고합니다. 이 경우 다음을 시도하십시오 :

    $ awk '$1~/[0-9]$/{printf "%s%s",sep,$2; sep=";"} ENDFILE{if(sep)print""; sep=""}' *.log
    value11;value12
    value21;value22
    
    
    위의 $1~/[0-9]$/  첫 단어가 숫자로 끝나는 줄을 선택하고 printf "%s%s",sep,$2  해당 줄에 두 번째 필드를 인쇄합니다.

    토론

    원래 명령은 :

    $ cat *.log | grep -oP "(?<=text1 ).*?(?= )|(?<=text2 ).*?(?= )" | tr '\n' '; '
    value11;value12;value21;value22;
    
    

    대부분의 유닉스 명령어를 사용할 때 cat  거의 필요하지 않습니다. 이 경우, 예를 들어 grep  파일 목록을 승인합니다. 그래서 우리는 여분의 cat 없이 쉽게 할 수 있습니다  처리하고 동일한 결과를 얻습니다.

    $ grep -hoP "(?<=text1 ).*?(?= )|(?<=text2 ).*?(?= )" *.log | tr '\n' '; '
    value11;value12;value21;value22;
    
    

  • 답변 # 2

    @ John1024에 동의하며이 문제에 어떻게 접근 할 것인지는 실제 텍스트가 무엇을 찾는 지에 달려 있습니다. 예를 들어 관심있는 라인이 text{1,2,...} 로 시작하는 경우  두 번째 필드에서 원하는 것은 무엇이든 될 수 있으며, 그의 접근 방식은 최적입니다. 그러나 첫 번째 필드의 값이 다르고 실제로 관심이있는 것은 valueXX 가있는 레코드입니다.  두 번째 필드에서 두 번째 필드를 키잉하는 접근 방식이 원하는 것일 수 있습니다.

    관심있는 텍스트가 valueXX 형식 인 경우 두 번째 필드를 예로들 수 있습니다.  ( XX )  두 번째 필드가 일치하는 레코드 만 처리 한 다음 FNR == 1 여부에 대한 간단한 조건부 테스트를 사용할 수 있습니다.   ';' 를 제어하기 위해  구분자 출력 및 ENDFILE  다음과 비슷한 새 줄을 제어하려면 :

    awk '$2 ~ /^value[0-9][0-9][0-9]*$/ {
        printf "%s%s", (FNR == 1) ? "" : ";", $2
    }
    ENDFILE {
        print ""
    }' file1.log file2.log
    
    

    사용/출력 예

    $ awk '$2 ~ /^value[0-9][0-9][0-9]*$/ {
        printf "%s%s", (FNR == 1) ? "" : ";", $2
    }
    ENDFILE {
        print ""
    }' file1.log file2.log
    value11;value12
    value21;value22
    
    

    사물을 살펴보고 실제 입력 파일을 고려한 다음이 두 가지 접근 방식 중 하나를 사용하십시오.

  • 답변 # 3

    잘 이해하면 values 가 필요합니다.  그러나 text[12] 를 검색  즉. 일치하는 검색어가 아닌 검색어와 일치하는 단어를 얻으려면 :

    $ awk -v s="^text[12]$" '                   # set the search regex *
    FNR==1 {                                    # in the beginning of each file
        b=b (b==""?"":"\n")                     # terminate current buffer with a newline
    }
    {
        for(i=1;i<NF;i++)                       # iterate all but last word
            if($i~s)                            # if current word matches search pattern
                b=b (b~/^$|\n$/?"":";") $(i+1)  # add following word to buffer
    }
    END {                                       # after searching all files
        print b                                 # output buffer
    }' *.log
    
    

    출력 :

    value11;value12
    value21;value22
    
    

    *  정규식은 예를 들어 ^(text1|text2)$ 일 수 있습니다. 이기도합니다.

  • 이전 javascript - 해결 방법 부분 헤드를 찾을 수 없습니다
  • 다음 javascript - 앱 순서를 염두에두고 jquery ajax 요청이 끝나기 전에 다른 함수가 실행됩니다