40,000줄의 파일이 있습니다.
head flower_all
0.992957746478873 0.00704225352112677
0.646410833917366 0.353589166082634
0.992957746478873 0.00704225352112677
0.992957746478873 0.00704225352112677
0.992957746478873 0.00704225352112677
0.992957746478873 0.00704225352112677
0.992957746478873 0.00704225352112677
0.992957746478873 0.00704225352112677
0.5 0.5
유효 숫자 3개만 유지하고 싶습니다. 내가 원하는 출력:
0.992 0.007
0.646 0.353
0.992 0.007
0.992 0.007
0.992 0.007
0.992 0.007
0.992 0.007
0.992 0.007
0.5 0.5
어떻게 해야 합니까?
답변1
그리고 awk
:
awk '{ printf("%.3g %.3g\n", $1, $2) }' file
데이터를 고려하면 이는 다음과 같습니다.
0.993 0.00704
0.646 0.354
0.993 0.00704
0.993 0.00704
0.993 0.00704
0.993 0.00704
0.993 0.00704
0.993 0.00704
0.5 0.5
0.00704에는 소수점 이하 5자리가 있지만 유효 숫자는 3개입니다.
정확히 소수점 이하 세 자리를 원하면 %.3f
대신 사용 %.3g
하고 얻으십시오.
0.993 0.007
0.646 0.354
0.993 0.007
0.993 0.007
0.993 0.007
0.993 0.007
0.993 0.007
0.993 0.007
0.500 0.500
위의 두 가지 변형은 GNU를 사용하여 가변 개수의 열로 일반화될 수 있습니다 awk
.
awk -v CONVFMT='%.3g' '{ for (i=1; i<=NF; ++i) $i+=0; print }' file
루프는 각 필드의 값을 $i+=0
부동 awk
소수점으로 다시 포맷하고 이를 고려합니다 CONVFMT
(동등한 작업을 수행함 $i=sprintf(CONVFMT, $i)
).
네가 원한다면자르다숫자:
awk '{ for (i=1; i<=NF; ++i) $i=sprintf("%.5s", $i); print }' file
이는 숫자를 문자열로 처리하고 5자 이후부터 잘라냅니다(모든 숫자가 10보다 작고 0보다 크다고 가정).
0.992 0.007
0.646 0.353
0.992 0.007
0.992 0.007
0.992 0.007
0.992 0.007
0.992 0.007
0.992 0.007
0.5 0.5
좀 더 일반적인 숫자 자르기의 경우:
awk '{ for (i=1; i<=NF; ++i) if (match($i,".*\\.[0-9]?[0-9]?[0-9]?")) $i=substr($i,RSTART,RLENGTH); print }' file
루프 내의 작업은 주어진 정규식 일치(일치하는 경우) 끝의 숫자를 자릅니다.
답변2
귀하의 데이터에는 1보다 큰 숫자가 없습니다. 점 앞에 더 많은 숫자가 있는 일부 값을 포함하도록 소스 파일을 확장했습니다.
$ cat infile
0.992957746478873 0.00704225352112677
0.646410833917366 0.353589166082634
0.992957746478873 0.00704225352112677
0.5 0.5
16.258137489137 333444.277775666
16.233399999999 333777.277111111
인쇄 기능
가능한 해결책 중 하나는 C 호환 printf 기능을 사용하는 것입니다(awk에는 하나가 있습니다).
f 형식(소수점 3자리(반올림))
소수점 이하 3자리까지 정확함(반올림):
$ awk '{ printf("%11.3f %11.3f\n", $1,$2) }' infile
0.993 0.007
0.646 0.354
0.993 0.007
0.500 0.500
16.258 333444.278
16.233 333777.277
0.992957746478873
로 반올림되었으니 참고하시기 바랍니다 0.993
.
g 형식(유효함(반올림))
3자리(유효) 숫자의 정확한 개수:
$ awk '{ printf("%9.3g %9.3g\n", $1,$2) }' infile
0.993 0.00704
0.646 0.354
0.993 0.00704
0.5 0.5
16.3 3.33e+05
16.2 3.34e+05
네 번째 숫자의 반올림에 유의하세요(예: 3.34e+05).
문자열(반올림되지 않음)
소수점 이하 3자리(반올림 없음)입니다.
GNU awk 사용:
$ gawk '{for(i=1;i<=NF;i++){
printf( "%12s ",gensub(/([0-9]+\.[0-9]{0,3}).*/, "\\1", "g", $i))};print""}
' infile
0.992 0.007
0.646 0.353
0.992 0.007
0.5 0.5
16.258 333444.277
16.233 333777.277
sed를 사용하십시오(아마도 더 빠를 것입니다):
$ sed -E 's/([0-9]+\.[0-9]{1,3})[^ ]*/\1/g' infile
0.992 0.007
0.646 0.353
0.992 0.007
0.5 0.5
16.258 333444.277
16.233 333777.277