입력에 슬래시(/)가 있는 경우 gawk의 산술(나누기) - 여러 필드 구분 기호가 있을 수 있습니까?

입력에 슬래시(/)가 있는 경우 gawk의 산술(나누기) - 여러 필드 구분 기호가 있을 수 있습니까?

다음과 유사한 줄이 포함된 파일이 있습니다(불행히도 이것은오직다른 소프트웨어의 출력 결과 형식):

1 2 3 5/2 7 17/5 9 10/3 15

다음 줄로 바꿔야 합니다.

1 2 3 2.5 7 3.4 9 3.33 15

즉, GAWK가 나눗셈을 수행하고 분수(유리수)를 5/2, 17/5 and 10/3 소수 값으로 바꾸길 원합니다.2.5, 3.4 and 3.33.

여러 FS(필드 구분 기호)를 시도했지만 아무것도 작동하지 않습니다. GAWK를 사용하여 이를 수행하는 좋은 방법은 무엇입니까? 감사해요.

slash (/)로 바꾸면 좀 더 편해질까요 colon (:)?

내가 왜 이 질문을 하는 걸까요? /..의 하위 문자열인지 검색하려고 합니다 . $i(답이 '예'이면 split()$i를 두 부분으로 나눈 다음 나누기를 수행합니다.)

필드가 -- $i로 시작 하는지 확인하기 위해 다른 곳에서 읽었으므로 , then , then 등을 시도했습니다 . 이들 중 어느 것도 작동하지 않습니다. 그래서 Awk의 특별한 캐릭터인 것 같아요 . 특수 문자의 복잡함을 피하기 위해 이것을 사용하자고 생각했습니다 .Fif ($i~/^F/)if ($i~///)if ($i~/"/"/)if ($i~/\//) (escaping / with a \)/:

답변1

필드를 반복하고 각 필드를 분할합니다 /. 분할로 인해 정확히 두 개의 하위 문자열이 생성되는 경우 이를 사용하여 필드의 새 값을 계산합니다.

$ awk '{ for (i=1; i<=NF; ++i) if (split($i,a,"/")==2) $i = a[1]/a[2] };1' file
1 2 3 2.5 7 3.4 9 3.33333 15

소수점 이하 두 자리의 경우 %.2f형식 지정자를 사용합니다 sprintf().

$ awk '{ for (i=1; i<=NF; ++i) { if (split($i,a,"/")==2) $i = sprintf("%.2f",a[1]/a[2]) } };1' file
1 2 3 2.50 7 3.40 9 3.33 15

마찬가지로,밀러:

$ mlr --nidx put 'for (k,v in $*) { a=splitnv(v,"/"); if (length(a)==2) { $[k]=a[1]/a[2] } }' file
1  2  3  2.500000  7  3.400000  9  3.333333  15
$ mlr --nidx put 'for (k,v in $*) { a=splitnv(v,"/"); if (length(a)==2) { $[k]=fmtnum(a[1]/a[2],"%.2f") } }' file
1  2  3  2.50  7  3.40  9  3.33  15

입력 및 출력 형식을 사용할 때 기본 필드 구분 기호 nidx는 단일 공백 ​​문자입니다. 이는 질문에 표시된 입력에 17개의 필드가 있으며 그 중 일부는 비어 있음을 의미합니다. 이는 출력에 복사되며 이는 공백이 유지됨을 의미합니다.

답변2

사용하기가 더 쉽습니다(또한 GNU 구현보다 더 많은 사전 설치된 시스템이 함께 제공됩니다 perl).perlgawkawk

perl -pe 's{(\d+)/(\d+)}{sprintf "%.2f", $1/$2}ge'

또는:

perl -pe 's{\d+/\d+}{sprintf "%.2f", eval$&}ge'

s숫자/숫자를 마지막 두 자리의 형식화된 나눗셈 결과로 바꿉니다 ..

perl -pe 's{(?<!\S)\d+/\d+(?!\S)}{sprintf "%.2f", eval$&}ge'

숫자/숫자 앞 및/또는 뒤에 흰색이 아닌 S리듬(예: 1/0x2, ...)을 A1/2그대로 둡니다.

관련 정보