awk printf 문자열을 10진수로 변환

awk printf 문자열을 10진수로 변환

일:

stdout은 로드 평균을 위에서부터 소수점 형식으로 출력합니다(예: 0.23).

세부 사항:

이 스크립트를 Chef의 검사로 구문 분석하고 그 결과가 어떤 것보다 크거나 작은지 확인해야 합니다. 예를 들면 다음과 같습니다.

describe command("top -b -n  1  | awk  '/load average/ { sub(/,/,\".\",$10); printf \"%f\n\",$10}'") do
  its("stdout") { should eq 0.00 }    
end

이 예에서는 ""를 반환합니다.

그런데 지금 생각해보면 안에 있는 파일들과 비교가 되더라구요./proc/loadavg

진전

다음 리소스를 사용하세요.평균 부하를 얻으려면 top을 사용하세요.

이 명령을 사용하면 출력이 잘 표현되지만 출력은 문자열이므로 계산할 수 없습니다.

martin@martinv-pc:~$ top -b -n  1  | awk '/load average/ { printf "%s\n", $10}'
0,63,

하지만 printf를 소수/부동 소수점으로 변경하려고 하면 오류가 발생합니다.

martin@martinv-pc:~$ top -b -n  1  | awk '/load average/ { printf "%f\n", $10}'
0.000000
martin@martinv-pc:~$ top -b -n  1  | awk '/load average/ { printf "%d\n", $10}'
0

소리가 들리지 않습니다. 잘라내어 보세요.나쁜 생각-- 작동 안함:

martin@martinv-pc:~$ top -b -n  1  | awk '/load average/ { printf "%s\n", $10}'|cut -c1-4
0,15
martin@martinv-pc:~$ top -b -n  1  | awk '/load average/ { printf "%s\n", $10}'|$((cut -c1-4))
-4: command not found

또 다른 시도:

martin@martinv-pc:~$ top -b -n  1  | awk '/load average/ BEGIN { printf "%.f\n", $10};'
awk: line 1: syntax error at or near BEGIN

질문:

문자열 값을 십진수/부동 소수점/정수로 변환하는 방법은 무엇입니까?

ps -o user,rss산출:

[vagrant@localhost ~]$ ps -o user,rss
USER       RSS
vagrant    736
vagrant   1080

답변1

~에서gawk: 쉼표 구분 기호로 형식화된 부동 소수점 숫자 합계:

대답은 --use-lc-numericgawk 옵션을 사용하는 것입니다.

--use -lc-번호

이는 gawk가 입력 데이터를 구문 분석할 때 로케일의 10진수 문자를 사용하도록 강제합니다. POSIX 표준에서는 이 동작을 요구하고 gawk는 --posix가 적용될 때 그렇게 하지만 기본값은 마침표가 소수점이 아닌 로케일에서도 레거시 동작을 따르고 마침표를 소수점으로 사용하는 것입니다. 성격. 이 옵션은 --posix 옵션의 전체 엄격함 없이 기본 동작을 재정의합니다.

귀하의 경우 다음 명령이 작동합니다.

top -b -n 1 | awk --use-lc-numeric '/load average/ { printf "%f\n", $10}'

답변2

,소수 구분 기호가 있는 로케일을 사용 중일 수 있습니다. 다음 방법 중 하나를 시도해 볼 수 있습니다.

  1. C 로캘 사용 top:

    LC_ALL=C top -b -n  1  | awk  '/load average/ { printf "%f\n",$10}'
    

    이는 마침표 대 쉼표 문제를 해결할 뿐만 아니라 load average사용자 언어로의 번역과 같은 텍스트 문제도 방지합니다.

  2. 쉼표를 점으로 바꾸십시오.

    top -b -n  1  | awk  '/load average/ { sub(/,/,".",$10); printf "%f\n",$10}'
    
  3. GNU의 경우 플래그를 awk사용하십시오.--use-lc-numeric@Leo의 추천또는 를 사용하십시오 POSIXLY_CORRECT=1 awk.

  4. awk또는 다음과 같은 POSIX 호환 구현을 사용하십시오.진짜 어이없네 기본적으로 로캘 규칙에 따라 숫자를 구문 분석하고 인쇄해야 합니다.

로드 평균을 얻는 보다 이식성 있는 명령은 입니다 uptime.

답변3

일:

sdout 위에서부터 소수점 형식의 로드 평균(예: 0.23)

해결책:

top -b -n  1  | perl -lane 'print "$1.$2" if /load average: (\d+)[,.](\d+)/'

노트:

그러면 1m 로드 평균이 검색됩니다. 이것이 당신이 원하는 것처럼 보일 수도 있지만, 분명히 해야 합니다. 필요한 경우 코드를 쉽게 수정하여 5분, 15분 또는 3분 모두에 대한 평균 로드를 검색할 수 있습니다.

지적한대로@테덴, uptime이 예보다 더 나은 출발점이 될 수 있습니다.top

처음 두 줄 이후에는암묵적으로결과로 무엇을 하고 싶은지 설명하세요. 당신이 취하고 싶은 다음 단계는 새로운 질문의 주제가 되어야 합니다.

Perl에서는 숫자가 자동으로 문자열로 변환되고 그 반대도 마찬가지입니다. 숫자를 나타내는 문자열에 대해 숫자 연산을 수행할 수 있습니다. 예를 들어print "$1.$2"+11.11


질문 2:

이 부분은 두 번째 질문에 관한 것입니다.전혀 관련이 없는첫 번째로.
OP에게 이 질문을 별도로 게시할 것을 촉구합니다..

문자열 값을 십진수/부동 소수점/정수로 변환하는 방법은 무엇입니까?

더 나은 작성 방법은 문자열에 대해 수치 비교를 수행하는 것입니다.요리사~의사양 확인.

해결책:

to_i문자열을 숫자 형식으로 사용하거나 변환합니다 to_f.

예:

describe command("echo 1.00") do
    its("stdout.to_f") { should be < 1.03 }
end

설명하다:

stdout이 문자열로 처리된다는 것은 완벽하게 이해됩니다. 그것도 아주 합리적으로,숫자비교하려면 두 숫자가...숫자여야 합니다. 다행스럽게도 편리한 Ruby 문자열 메서드인 to_i, to_f및 를 사용하여 변환을 수행할 수 있습니다 .to_rto_c

답변4

문제는 추출된 필드가 소수 구분 기호로 쉼표를 사용하는 반면 awk는 부동 소수점 숫자가 포인트를 사용할 것으로 예상한다는 것입니다.

이것은 문제를 재현합니다.

$ LC_ALL=de_DE top -bn 1 | awk 'NR==1'
top - 08:37:07 up 1 day, 10:22,  5 users,  load average: 0,17, 0,24, 0,26

보시다시피 숫자는 쉼표를 소수 구분 기호로 사용합니다. 다음과 같은 것이 필요합니다.

$ LC_ALL=en_US top -bn 1 | awk 'NR==1'
top - 08:38:28 up 1 day, 10:23,  5 users,  load average: 0.56, 0.34, 0.30

locale -a그러나 이는 시스템에 설치된 로케일 에 따라 다릅니다 (확인). 로캘 C설정은 항상 사용할 수 있습니다.

$ LC_ALL=C top -bn 1 | awk 'NR==1'
top - 08:40:35 up 1 day, 10:25,  5 users,  load average: 0.50, 0.39, 0.31

그러나 첫 번째 행만 추출하기 위해 top을 사용하는 것은 약간 과잉입니다. 가동 시간 활용도 향상:

$ LC_ALL=C uptime
08:42:08 up 1 day, 10:27,  5 users,  load average: 0.35, 0.37, 0.31

하지만 더 나은 방법은 /proc/loadavg파일을 읽는 것입니다.

$ cat /proc/loadavg 
0.29 0.34 0.30 1/468 15084

그건 그렇고, 이것은 로케일과 무관합니다. 첫 번째 숫자는 1분 로드 평균입니다. 이를 선택하고 원하는 형식으로 인쇄하세요.

$ awk '{printf( "%s\n %f\n %d\n", $1, $1, $1 )}' /proc/loadavg
0.35
0.350000
0

1, 5, 15분 로드 평균 사용량의 경우:

$ awk '{printf( "%7.3f %7.3f %5.2f\n", $1, $2, $3 )}' /proc/loadavg
 0.150   0.340  0.33

관련 정보