"e" 없이 공학용 형식을 사용하세요.

"e" 없이 공학용 형식을 사용하세요.

과학적 표기법으로 된 숫자가 포함되어 있지만 기호가 없는 파일을 조작하려고 합니다 e. 즉 1.2e+3, 1.2+3.

제가 생각할 수 있는 가장 간단한 방법은 로 awk바꾸고 , 함수를 사용하고, 새 파일에서 계산을 수행하는 것입니다. 음수 값의 경우에도 마찬가지입니다. 따라서 다음 명령을 사용하여 간단한 수정을 수행할 수 있습니다.+e+gsub

awk '{gsub("+", "e+", $1); print $1, $2, $3, $4, $5}' file_in

모든 열에서 동일한 작업을 수행합니다.

그러나 파일에는 음수도 포함되어 있어 상황이 더 복잡해집니다. 샘플 파일은 다음과 같습니다.

 1.056000+0 5.000000-1 2.454400-3 2.914800-2 8.141500-6
 2.043430+1 5.000000-1 2.750500-3 2.698100-2-2.034300-4
 3.829842+1 5.000000-1 1.969923-2 2.211364-2 9.499900-6
 4.168521+1 5.000000-1 1.601262-2 3.030919-2-3.372000-6
 6.661784+1 5.000000-1 5.250575-2 3.443669-2 2.585500-5
 7.278104+1 5.000000-1 2.137055-2 2.601701-2 8.999800-5
 9.077287+1 5.000000-1 1.320498-2 2.961020-2-1.011600-5
 9.248130+1 5.000000-1 3.069610-3 2.786329-2-6.317000-5
 1.049935+2 5.000000-1 4.218794-2 3.321955-2-5.097000-6
 1.216283+2 5.000000-1 1.432105-2 3.077165-2 4.300300-5

조작 및 계산을 위해 이러한 파일을 사용하는 방법에 대한 아이디어가 있습니까?

답변1

이 출력이 맞나요?

 1.056000e+0 5.000000e-1 2.454400e-3 2.914800e-2 8.141500e-6
 2.043430e+1 5.000000e-1 2.750500e-3 2.698100e-2-2.034300e-4
 3.829842e+1 5.000000e-1 1.969923e-2 2.211364e-2 9.499900e-6
 4.168521e+1 5.000000e-1 1.601262e-2 3.030919e-2-3.372000e-6
 6.661784e+1 5.000000e-1 5.250575e-2 3.443669e-2 2.585500e-5
 7.278104e+1 5.000000e-1 2.137055e-2 2.601701e-2 8.999800e-5
 9.077287e+1 5.000000e-1 1.320498e-2 2.961020e-2-1.011600e-5
 9.248130e+1 5.000000e-1 3.069610e-3 2.786329e-2-6.317000e-5
 1.049935e+2 5.000000e-1 4.218794e-2 3.321955e-2-5.097000e-6
 1.216283e+2 5.000000e-1 1.432105e-2 3.077165e-2 4.300300e-5

암호:

perl -lne 's/(\.\d+)(\+|\-)/\1e\2/g; print' sample

설명하다:

  • -lne줄 끝 처리, 각 입력 줄 처리 및 다음 코드 실행

  • s/(\.\d+)(\+|\-)/\1e\2/g:

    • 바꾸다( s)
    • (.\d+)(\+|\-)두 그룹(점과 숫자) 및 (더하기 또는 빼기 기호) 찾기
    • \1e\2첫 번째 세트로 교체한 다음 e두 번째 세트로 교체하세요.
    • g전역 - 각 줄의 첫 번째 교체에서 멈추지 않고 가능한 모든 적중을 처리합니다.
  • print이 줄을 인쇄하세요

  • sample입력 파일

누락된 경우 공간이 추가됩니다. 실제로 어쨌든 숫자 사이에 공백이 남습니다. 즉. 특정 상황에서 공백이 두 개 있는 경우 출력에는 공백이 하나만 표시됩니다.

perl -lne 's/(\.\d+)(\+|\-)(\d+)(\s*)/\1e\2\3 /g; print' sample

대부분의 내용은 이전 글과 유사합니다. 새로운 것은 (\d+)그룹 NR 3과 (\s*)그룹 NR 4입니다. *여기서 의미하는 바는 선택 사항입니다. 대신에 \4no를 사용하십시오 . 그러나 공간이 있습니다.

출력은 다음과 같습니다:

 1.056000e+0 5.000000e-1 2.454400e-3 2.914800e-2 8.141500e-6 
 2.043430e+1 5.000000e-1 2.750500e-3 2.698100e-2 -2.034300e-4 
 3.829842e+1 5.000000e-1 1.969923e-2 2.211364e-2 9.499900e-6 
 4.168521e+1 5.000000e-1 1.601262e-2 3.030919e-2 -3.372000e-6 
 6.661784e+1 5.000000e-1 5.250575e-2 3.443669e-2 2.585500e-5 
 7.278104e+1 5.000000e-1 2.137055e-2 2.601701e-2 8.999800e-5 
 9.077287e+1 5.000000e-1 1.320498e-2 2.961020e-2 -1.011600e-5 
 9.248130e+1 5.000000e-1 3.069610e-3 2.786329e-2 -6.317000e-5 
 1.049935e+2 5.000000e-1 4.218794e-2 3.321955e-2 -5.097000e-6 
 1.216283e+2 5.000000e-1 1.432105e-2 3.077165e-2 4.300300e-5 

답변2

예를 들어 다음 과 같이 사용할 수도 있습니다 sed.

<infile sed -E 's/([0-9])([+-])([0-9])/\1e\2\3/g' | awk '{ print $1 + 0 }'

그러나 이는 OP 목록의 열이 때때로 구분되지 않는다는 점을 고려하지 않습니다. 적절한 정밀도를 갖춘 해결 방법은 다음과 같습니다.

<infile sed -E 's/.{11}/& /g'       |
sed -E 's/([0-9])([+-])/\1e\2/g'    |
gawk '{ print $1 + 0 }' OFMT='%.7g'

산출:

1.056
20.4343
38.29842
41.68521
66.61784
72.78104
90.77287
92.4813
104.9935
121.6283

관련 정보