텍스트 파일에서 변수를 추출하는 쉬운 방법이 있습니까?
예를 들어 다음과 같은 출력이 제공됩니다 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)