서식이 지정된 텍스트에서 값 추출

서식이 지정된 텍스트에서 값 추출

텍스트 파일에서 변수를 추출하는 쉬운 방법이 있습니까?

예를 들어 다음과 같은 출력이 제공됩니다 ab.

This is ApacheBench, Version 2.3 <$Revision: 1638069 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking bar (be patient)
Finished 1206 requests


Server Software:        Jetty(9.0.z-SNAPSHOT)
Server Hostname:        bar
Server Port:            5500

Document Path:          /foo/1
Document Length:        148 bytes

Concurrency Level:      15
Time taken for tests:   30.041 seconds
Complete requests:      1206
Failed requests:        0
Total transferred:      359686 bytes
HTML transferred:       178636 bytes
Requests per second:    40.15 [#/sec] (mean)
Time per request:       373.643 [ms] (mean)
Time per request:       24.910 [ms] (mean, across all concurrent requests)
Transfer rate:          11.69 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       47  108  36.0     98     328
Processing:    73  264 782.5    150    7951
Waiting:       73  255 721.5    148    7886
Total:        129  371 783.5    259    8039

Percentage of the requests served within a certain time (ms)
  50%    259
  66%    293
  75%    324
  80%    340
  90%    413
  95%    525
  98%    683
  99%   6421
 100%   8039 (longest request)

name: value값(일치 , 아래 예 참조)을 추출하여 한 단계로 변수에 할당하고 싶습니다 . ( ab일부 데이터는 csv로 내보낼 수 있지만 나머지는 서식이 지정된 텍스트로만 사용할 수 있다는 것을 알고 있습니다 .)

지금까지 내가 찾은 최고는 다음과 같습니다.

path=$(cat text|grep 'Document Path:'|awk -F: '{ split($2, z, " "); print z[1]}')
total=$(cat text|grep 'Total transferred:'|awk -F: '{ split($2, z, " "); print z[1]}')
#[...]

그런데 이게 좀 반복되는 것 같아요Ward - 작업을 위한 더 쉬운 방법이나 더 나은 도구가 있습니까?

답변1

나는 일반적으로 다음 패턴을 사용합니다.

. <(
    awk 'BEGIN{print "shellvarname=\"value\""}'
)

awk이는 쉘 변수 할당 구문에 사용할 수 있는 명령문을 생성하는 데 사용됩니다 . 이 결과는 ( .)에서 나온 것입니다.

특정 요구 사항에 따라 다음과 같은 옵션이 있습니다.

. <(
    awk -F': *' '
      /Document Path/{printf "%s=\"%s\"\n", "path", $2}
      /Total transferred/{printf "%s=\"%s\"\n", "total", $2}
    ' file
)

또는 더 짧음

. <(
    awk '
      /Document Path/{printf "%s=\"%s\"\n", "path", $3}
      /Total transferred/{printf "%s=\"%s\"\n", "total", $3}
    ' file
)

답변2

1-4 단어가 포함된 모든 줄을 찾은 다음 를 사용하고 :단어 사이의 공백을 밑줄로 바꾸고 variable=value쌍으로 인쇄합니다. 그런 다음 전체 콘텐츠를 전달하여 eval설정할 수 있습니다. 예를 들어:

$ awk -F': *' '/^(\S+\s*){1,4}:/{gsub(/ /,"_",$1);print $1"=\""$2"\""}' file
Server_Software="Jetty(9.0.z-SNAPSHOT)"
Server_Hostname="bar"
Server_Port="5500"
Document_Path="/foo/1"
Document_Length="148 bytes"
Concurrency_Level="15"
Time_taken_for_tests="30.041 seconds"
Complete_requests="1206"
Failed_requests="0"
Total_transferred="359686 bytes"
HTML_transferred="178636 bytes"
Requests_per_second="40.15 [#/sec] (mean)"
Time_per_request="373.643 [ms] (mean)"
Time_per_request="24.910 [ms] (mean, across all concurrent requests)"
Transfer_rate="11.69 [Kbytes/sec] received"
Connect="47  108  36.0     98     328"
Processing="73  264 782.5    150    7951"
Waiting="73  255 721.5    148    7886"
Total="129  371 783.5    259    8039"

-F': *필드 구분 기호 :뒤에 0개 이상의 공백이 오도록 설정합니다 . 그런 다음 스크립트는 행이 공백이 아닌 문자("단어")가 1~4개 발생하고 그 뒤에 0개 이상의 공백이 오는 문자열과 일치하는지 확인한 다음 :. 이 줄 때문에 4를 사용하고 있습니다.

Time taken for tests:   30.041 seconds

그런 다음 일치하는 줄에 대해 첫 번째 필드의 모든 공백을 밑줄( gsub(/ /,"_",$1))로 바꾼 다음 첫 번째 필드인 an =과 인용된 두 번째 필드를 인쇄합니다. 문자열을 인쇄 하려면 따옴표로 묶어야 하기 때문에 따옴표로 awk묶인 문자열을 인쇄하려면 $2따옴표를 이스케이프해야 합니다 " \"".

원하는 출력이 생성되면 이제 다음을 eval사용하여 변수를 읽을 수 있습니다.

$ eval $(awk -F': *' '/^(\S+\s*){1,4}:/{gsub(/ /,"_",$1);print $1"=\""$2"\""}' file)
$ echo $Transfer_rate 
11.69 [Kbytes/sec] received

또는 직접 가져오세요.

. <(awk -F': *' '/^(\S+\s*){1,4}:/{gsub(/ /,"_",$1);print $1"=\""$2"\""}' file)

중요한: 위험할 수도 있습니다. eval또는 파일을 가져오면 사용자가 제공한 모든 코드가 실행됩니다. 위험한지 확인하지 않습니다. 어떤 이유로 스크립트가 awk위험한 것을 반환하면 행복하게 실행됩니다. 따라서 위 명령을 실행하기 전에 출력 결과를 확인하십시오. 허용되는 답변도 마찬가지입니다. 다른 프로그램에서 반환된 코드를 맹목적으로 실행하는 것은 항상 위험합니다.rm ~/*eval


위의 내용은 GNU에서는 작동 awk하지만 더 간단한 구현에서는 작동하지 않습니다 awk. 시스템에서 작동하지 않으면 다음을 시도해 보십시오.

. <(awk -F': *' '/.*\s*:   *:/{gsub(/ /,"_",$1);print $1"=\""$2"\""}' file)

관련 정보