파일의 특정 열에 있는 숫자의 내부 서식 지정 [닫기]

파일의 특정 열에 있는 숫자의 내부 서식 지정 [닫기]

col을 다음과 같은 Amount2자리 십진수 형식으로 포맷 하려고 합니다 .10001000.00

다음과 같은 샘플 파일이 있습니다.

Bank|Branch|Comment|Amount|Extra1|Extra2
xyz|we||100||
xyz|we||100.1||
xyz|we|paid for inv# 34VM23-SEP-20|23459900.00||
xyz|errt||-230.0||
xyz|ss||234.78||
xyz|we|valid|990.2||
xyz|we|9922.9 paid|9922.9||
xyz|we||.9||
xyz|we||.0||
xyz|we||.00||

나는 awk -F"|" '{OFS=FS}''{printf ("%.2f",$4) ; print }' test.csv결과를 얻으려고 노력했다.

0.00Bank|Branch|Comment|Amount|Extra1|Extra2
100.00xyz|we||100||
100.10xyz|we||100.1||
23459900.00xyz|we|paid for inv# 34VM23-SEP-20|23459900.00||
-230.00xyz|errt||-230.0||
234.78xyz|ss||234.78||
990.20xyz|we|valid|990.2||
9922.90xyz|we|9922.9 paid|9922.9||
0.90xyz|we||.9||
0.00xyz|we||.0||
0.00xyz|we||.00||
0.00

또한 헤더 행을 피하고 원본 파일로 바꾸고 싶습니다. 올바른 방향을 알려주세요. 감사해요

답변1

귀하의 awk 코드에 결함이 있습니다. 먼저 수정된 값 $4와 전체 라인을 인쇄합니다.

올바른 버전은 다음과 같습니다.awk -F"|" 'NR<=1{print $0;next} {{printf($1"|" $2"|"$3"|%.2f|"$5"|"$6"\n",$4)}}' test

$ awk -F"|" 'NR<=1{print $0;next}  {{printf($1"|" $2"|"$3"|%.2f|"$5"|"$6"\n",$4)}}' test
bank|Branch|Comment|Amount|Extra1|Extra2
xyz|we||100,00||
xyz|we||100,00||
xyz|we|paid for inv# 34VM23-SEP-20|23459900,00||
xyz|errt||-230,00||
xyz|ss||234,00||
xyz|we|valid|990,00||
xyz|we|9922.9 paid|9922,00||
xyz|we||0,00||
xyz|we||0,00||
xyz|we||0,00||

변경되지 않은 필드와 원하는 대로 수정된 필드를 모두 인쇄해야 합니다4. 첫 번째 줄을 처리되지 않은 상태로 두려면 NR을 테스트하고 수정 없이 해당 줄을 인쇄한 다음 next두 번째 줄을 계속 진행하세요.

편집하다원래 명령과 내 버전이 존재하는 십진수를 유지하지 않고 0으로 설정하기 때문에 내 awk 버전에 문제가 있을 수 있습니다. 이것이 당신에게 효과가 있는 것 같아요. 아무래도 우리 동네 사람들과 관련이 있는 것 같아요. 예를 들어 내 컴퓨터에서는 234.78.234,00

또 다른 해결책은 다음과 같습니다.폴 페던트주석은 $4의 값을 직접 변경하고 나중에 인쇄하는 것입니다.

plonky@sd-143012:~/work$ awk -F '|' '{ {OFS=FS} if (FNR > 1) $4 = sprintf ("%.2f", $4); print; }'  test
bank|Branch|Comment|Amount|Extra1|Extra2
xyz|we||100,00||
xyz|we||100,00||
xyz|we|paid for inv# 34VM23-SEP-20|23459900,00||
xyz|errt||-230,00||
xyz|ss||234,00||
xyz|we|valid|990,00||
xyz|we|9922.9 paid|9922,00||
xyz|we||0,00||
xyz|we||0,00||
xyz|we||0,00||

답변2

다음과 같이 작동해야 합니다.

awk -F '|' 'FNR>1 {printf "%s|%s|%s|%.2f|%s|%s\n", $1,$2,$3,$4,$5,$6}'

이미 가지고 -F '|'있지만 필드 구분 기호가 있습니다.

현재 입력 파일의 입력 레코드 번호를 사용하여 첫 번째 줄을 건너뛰고 싶다고 말합니다 FNR>1. FNRawk는 줄 기반 판독기이므로 다음과 같이 >1표시됩니다.첫 번째 줄 이후 처리.

을 사용하는 것도 맞지만 printf구문이 원하는 결과를 얻지 못합니다. 요구 사항에 따라 전체 라인을 인쇄하도록 확장할 수 있습니다.

또한 줄 끝의 줄 반환을 잊어버렸기 \n때문에 이상한 레이아웃이 생성되었습니다.

답변3

그리고밀러

mlr --csvlite --fs '|' put '$Amount = fmtnum($Amount,"%.2f")' file

파일을 수정하려면 -I명령줄 스위치를 추가하세요.

답변4

Raku 사용(옛 Perl6)

split명시적 호출 과 호출을 통해 매우 기계적인 작업을 수행하기 위해 Raku를 사용할 수도 있습니다 join. 이 방법으로 동일한 숫자 형식 코드를 사용하여 다른 열 구분 기호(예: 쉼표)로 변경할 수 있습니다.

~$ raku -e 'for lines.skip(1) {my @a = .split("|"); .subst(@a[3], sprintf( "%.2f", @a[3] )).join("|").put };'

tmp또한 먼저 헤더를 저장한 다음 서식이 지정된 데이터 행을 추가하는 파일을 만드는 코드를 작성했습니다 . 귀하가 요청한 것은 아니지만 작동합니다. 또한 이 코드를 사용하면 서식을 지정하려는 열 외에 행당 총 열 수를 알 필요가 없습니다.

함께 넣어보세요:

~$ raku -e '.say for lines[0];' < bank.txt > tmp
~$ raku -e 'for lines.skip(1) {my @a = .split("|"); .subst(@a[3], sprintf( "%.2f", @a[3] )).join("|").put };' < bank.txt >> tmp

산출:

Bank|Branch|Comment|Amount|Extra1|Extra2
xyz|we||100.00||
xyz|we||100.10||
xyz|we|paid for inv# 34VM23-SEP-20|23459900.00||
xyz|errt||-230.00||
xyz|ss||234.78||
xyz|we|valid|990.20||
xyz|we|9922.90 paid|9922.9||
xyz|we||0.90||
xyz|we||0.00||
xyz|we||0.00||

HTH.

https://raku.org/

관련 정보