CSV 테스트 결과 파일에서 램프 기간 동안 테스트 결과를 제거하는 방법은 무엇입니까?

CSV 테스트 결과 파일에서 램프 기간 동안 테스트 결과를 제거하는 방법은 무엇입니까?

CSV 파일에 테스트 결과가 있습니다. 첫 번째 필드에는 밀리초 단위의 타임스탬프가 있습니다.

다음은 CSV 파일의 샘플 레코드입니다.

1628689875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17

램프 업(시작 시간으로부터 5분) 및 램프 다운 기간(지난 5분) 동안의 테스트 결과를 삭제하고 필터링된 테스트 결과를 CSV 파일에 쓰고 싶습니다.

하드코딩된 값을 사용해 보았습니다.

#!/usr/bin/awk -f

  BEGIN {
    endTime=1628689875326
    startTime=1628689875326-300*1000
    offset=1628689875326-3900*1000

    FS=","
    rowCount=0
  }
  {

    if ($1> startTime && $1<offset){
        rowCount++
        print $0
    }
  }

답변1

awk를 호출하기 위해 shebang을 사용하는 대신 shebang을 사용하여 쉘을 호출한 다음 awk를 호출하십시오. 바라보다https://stackoverflow.com/a/61002754/1745001왜.

나는 당신이 원하는 것을 할 것입니다:

#!/usr/bin/env bash

awk -F',' '
    NR==FNR {
        if (NR==2) {
            fiveMins = 5*60*1000*1000
            begTime  = $1 + fiveMins
        }
        endTime = $1 - fiveMins
        next
    }
    (FNR==1) || ( (begTime <= $1) && ($1 <= endTime) ) {
        print
        rowCount++
    }
    END {
        print rowCount+0 | "cat>&2"
    }
' "$1" "$1"

tail또는 다음을 사용하여 마지막 행의 타임스탬프를 얻을 수 있습니다.@GreenOnline의 답변) awk에서 파일을 두 번 읽는 대신:

#!/usr/bin/env bash

awk -v lastTime="$(tail -n 1 "$1" | cut -d',' -f1)" -F',' '
    NR==2 {
        fiveMins = 5*60*1000*1000
        begTime  = $1 + fiveMins
        endTime  = lastTime - fiveMins
    }
    (NR==1) || ( (begTime <= $1) && ($1 <= endTime) ) {
        print
        rowCount++
    }
    END {
        print rowCount+0 | "cat>&2"
    }
' "$1"

어느 쪽이든 다음과 같이 호출할 수 있습니다.

scriptname input.csv > output.csv

> output.csv또는 출력 파일 이름을 하드코딩해도 괜찮다면 쉘 스크립트에서 awk 스크립트 뒤에 추가하십시오.

위의 내용은 CSV에 출력에 인쇄하려는 헤더 행이 있다고 가정합니다.

Shebang을 사용하지 않고 awk를 호출하면 쉘을 사용하여 가장 잘하는 작업, 즉 다른 명령을 호출하고 스크립트 인수를 여러 번 사용한 다음 awk를 호출하여 가장 잘하는 작업, 즉 텍스트를 처리할 수 있습니다. 부팅 비율 다른 방법은 더 깨끗하고 강력하며 효율적인 스크립트입니다.

답변2

하드 코딩된 솔루션

하드코딩된 시간 스크립트에서 문제는 다음과 같습니다.

  • offset보다 작 startTime으므로 if조건은

    $1> startTime && $1<offset
    

    할 수 있는안 돼요그건 진실이야.

그 이유는 아직 5분( =300초) startTime이 남았는데 , 아직 65분( =3900초) 이 남아 있기 때문입니다.5*60offset65*60

해결책은 초기화 프로그램을 다음으로 변경하는 것입니다.

    startTime=1628689875326-3900*1000*1000
    offset=1628689875326-300*1000*1000

그러면 관련 시간이 다음으로 설정됩니다.

endTime = 1628689875326
startTime = endTime - (3900*1000*1000) =  1624789875326
5 minutes before end = endTime - (300*1000*1000)  = 1628389875326

이제 다음과 같은 로그 파일이 제공됩니다.

1624789875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1624789875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875325,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628689875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17

달리기

more test.log | ./filter.awk

원하는 결과를 제공합니다

1624789875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875325,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17

더 나은 솔루션 - 시작 시간 확인

그러나 귀하의 질문을 자세히 조사해 보면 몇 가지 사항이 잘 정의되어 있지 않은 것으로 나타났습니다.

  • 스크립트에서는 startTime실제 로그의 시작이 아니라 필터의 시작일 수 있습니다. 로그의 시작 시간은 5분 전입니다.

    1624789875326 - 300*1000*1000 = 1624489875326
    
  • 당신은 시간이 밀리초 단위라고 말 *1000*1000했지만마이크로초.

그럼에도 불구하고, 시작 시간(로그 파일의 첫 번째 줄부터 시작)을 자동으로 찾고 램프 시간을 계산하여 필터의 시작 시간을 계산하는 솔루션이 있습니다.

또한 필터 시간의 끝도 계산합니다(하드코딩된 스크립트와 동일한 방식).종료 시간을 입력해야 하지만, 이는 로그의 마지막 타임스탬프입니다.

#!/usr/bin/awk -f
  
  BEGIN {
    rampTimeMins=5
    rampTimeMillis=rampTimeMins*60*1000
    rampTimeMicros=rampTimeMins*60*1000*1000

    # Enter the start time
    # (not required, if NR conditional is used)
    startTime=0
    # Calculate Start filter time in microseconds 
    # (not required, if NR conditional is used)
    filterStartTime=startTime+rampTimeMicros

    # Enter the end time (required)
    endTime=1628689875326
    # Calculate End filter time in microseconds
    filterEndTime=endTime-rampTimeMicros

    FS=","
    rowCount=0
  }

  {
    if (NR==1){
      startTime=$1
      filterStartTime=startTime+rampTimeMicros
    }
    if ($1> filterStartTime && $1<filterEndTime){
      rowCount++
      print $0
    }
  }

  END {
    print rowCount
  }

참고 1: CSV의 첫 번째 행이 헤더인 경우 NR==1다음으로 변경하세요.NR==2

노트 2: 마이크로초 대신 밀리초를 사용하려면 rampTimeMicros로 변경하면 됩니다 rampTimeMillis.

다음은 다음을 포함하는 샘플 로그 파일입니다.추가의로그의 실제 시작 시간인 초기 시간(필터의 시작 시간이 아님)

1624489875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1624489875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1624789875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1624789875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875325,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628689875326,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17

어느 것으로 실행할 것인가

more test.log | ./filter.awk

이전과 동일한 결과를 제공합니다

1624789875327,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
1628389875325,327,3.1 HTTP Request /api/StaffPortal,200,OK,Concurrency Thread Group   SignIn-ThreadStarter 1-5,text,true,,73018,17,17
2

하지만 추가 줄이 있습니다.


최종 솔루션 - 종료 시간 얻기

줄을 바꾸면

    endTime=1628689875326

도착하다

    "tail -1 test.log | cut -d, -f1" | getline endTime

그러면 마지막 타임스탬프를 얻었으므로 스크립트를 더 이상 편집할 필요가 없습니다.앞으로스크립트가 실행됩니다. 일반 용도로 제작됨

    "tail -1 "ARGV[1]" | cut -d, -f1" | getline endTime

또는 더 나은 방법은 (안전한 측면을 유지하기 위해) 다음과 같이 생성된 하위 쉘에 인용된 파일 이름을 전달하는 것입니다.에드의 코멘트:

생성된 하위 쉘에 따옴표 없이 파일 이름을 전달하지 않도록 으로 변경합니다(이 모든 것은 글로빙, 토큰화, 보안 등을 의미함 "tail -1 "ARGV[1]") ."tail -1 \047"ARGV[1]"\047

\047작은따옴표(FWIW: \042큰따옴표)는 어디에 있습니까?

"tail -1 \047"ARGV[1]"\047 | cut -d, -f1" | getline endTime

따라서 최종 스크립트는 다음과 같습니다.

#!/usr/bin/awk -f
  
  BEGIN {
    rampTimeMins=5
    rampTimeMillis=rampTimeMins*60*1000
    rampTimeMicros=rampTimeMins*60*1000*1000

    # Enter the start time
    # (not required, if NR conditional is used)
    startTime=0
    # Calculate Start filter time in microseconds 
    # (not required, if NR conditional is used)
    filterStartTime=startTime+rampTimeMicros

    # Derive the end time
    "tail -1 \047"ARGV[1]"\047 | cut -d, -f1" | getline endTime
    # Calculate End filter time in microseconds
    filterEndTime=endTime-rampTimeMicros

    FS=","
    rowCount=0
  }

  {
    if (NR==1){
      startTime=$1
      filterStartTime=startTime+rampTimeMicros
    }
    if ($1> filterStartTime && $1<filterEndTime){
      rowCount++
      print $0
    }
  }

  END {
    print rowCount
  }

참고 1: CSV의 첫 번째 행이 헤더인 경우 NR==1다음으로 변경하세요.NR==2

다음 명령( filter.awk) 을 사용하여 스크립트를 실행합니다.

./filter.awk test.log

아니요

more test.log | ./filter.awk

인용하다:

답변3

주어진 예제 스크립트는 다음 수정 사항으로 업데이트되었습니다.

  1. 입력 파일의 두 번째 줄의 시작 시간을 기준으로 filterStartTime합계를 계산합니다.filterEndTime
  2. 추가 분석을 위해 파일에 출력 쓰기
#!/usr/bin/awk -f
  BEGIN {
    testDurationMins=60
    rampTimeMins=5
    outputFileName="test-result-filtered-without-rampup.jtl"

    rampTimeMillis=rampTimeMins*60*1000

    # Enter the start time
    # (not required, if NR conditional is used)
    startTime=0
    # Calculate Start filter time in milliseconds
    # (not required, if NR conditional is used)
    filterStartTime=startTime+rampTimeMillis

    # Filter end time
    filterEndTime=0

    # Calculate the test duration  in milliseconds
    testDurationMillis=testDurationMins*60*1000

    FS=","
    rowCount=0
  }
  {

    if (NR==1){
      #Write header to the output file
      print > outputFileName
    }
    if (NR==2){
      #Set the filter start and end times
      startTime=$1
      filterStartTime=startTime+rampTimeMillis
      filterEndTime=filterStartTime+testDurationMillis
    }
    if (NR>2 && $1> filterStartTime && $1<filterEndTime){
      rowCount++
      print >> outputFileName
    }
  }
  END {
    print "" rowCount
  }

관련 정보