awk printf 명령을 사용하여 출력 형식을 올바르게 지정하는 방법은 무엇입니까?

awk printf 명령을 사용하여 출력 형식을 올바르게 지정하는 방법은 무엇입니까?

다음 파일이 있습니다.

echo filename
    dfT08r352|30.5|2010/06/01|2016/08/29|2281|6.24503764544832|74.9404517453799|
    zm00dr121|37|2008/03/05|2011/09/12|1285.95833333333|3.52076203513575|42.249144421629|
    ccvd00121|41.6|2008/03/05|2012/03/05|1461|4|48|
    sddf00121|39.6|2008/03/05|2012/09/10|1649.95833333333|4.51733972165184|54.208076659822|
    fttt00121|41|2008/03/05|2013/09/16|2020.95833333333|5.53308236367785|66.3969883641342|
    ghhyy0121|42.2|2008/03/05|2014/03/18|2203.95833333333|6.03410905772302|72.4093086926762|

awk printf를 사용하여 이 파일을 다음과 같은 원하는 형식으로 포맷하려고 합니다.

  1. 동일한 필드 순서 유지(왼쪽-->오른쪽)
  2. 쉼표 "," FS가 있습니다
  3. 나한테만필드 3개($5, $6, $7)모든 숫자는 4자리입니다. 4자리 미만인 경우 앞에 0이 표시되고 0123.12 또는 1234.10과 같이 점 뒤에 2자리만 표시됩니다.

나는 다음 awk 명령을 작성했습니다

awk -F"|" '{print $1","$2","$3","$4}{format = "%04.2f,%04.2f,%04.2f,"}{printf format, $5,$6,$7}' filename

그러나 다음 출력에는 다음과 같은 문제가 있습니다.

  1. 순서가 아님(왼쪽-->오른쪽)

  2. 앞에 0이 없음

    dfT08r352,30.5,2010/06/01,2016/08/29
    2281.00,6.25,74.94,zm00dr121,37,2008/03/05,2011/09/12
    1285.96,3.52,42.25,ccvd00121,41.6,2008/03/05,2012/03/05
    1461.00,4.00,48.00,sddf00121,39.6,2008/03/05,2012/09/10
    1649.96,4.52,54.21,fttt00121,41,2008/03/05,2013/09/16
    2020.96,5.53,66.40,ghhyy0121,42.2,2008/03/05,2014/03/18
    

누군가 내 오류가 무엇인지, 해결 방법을 알려줄 수 있나요?

답변1

필드의 순서는 올바른데 첫 번째 print 문에 개행 문자(출력 레코드 구분 기호)가 추가되어 데이터가 거기에 있지만 예기치 않게 래핑되었습니다.

두 번째 문제는 printf에 너비 4를 사용하도록 지시하는 것입니다. 소수점과 그 뒤에 두 자리를 포함하고 패딩 없이 한 자리만 남겨 두는 것입니다. 데이터를 총 4개의 숫자로 채울 수 있도록 너비를 5로 사용해 보세요. 4자리를 원하시면앞으로소수점을 입력하고 너비를 7로 변경합니다.

다음은 귀하가 원하는 것을 출력하기 위해 귀하의 프로그램에 최소한의 변경 사항을 적용한 것입니다.

awk -F"|" '{
  format = "%05.2f,%05.2f,%05.2f"; 
  print $1","$2","$3","$4"," sprintf(format, $5,$6,$7)}' filename

{ }여러 블록을 하나로 결합하고 명령문을 하나로 인쇄했습니다 .

처음부터 awk 문을 작성한다면 다음과 같이 할 수 있습니다.

awk -v FS=\| -v OFS=, '{
  $5=sprintf("%05.2f", $5); 
  $6=sprintf("%05.2f", $6); 
  $7=sprintf("%05.2f", $7); 
  print $1,$2,$3,$4,$5,$6,$7}' filename

입력 필드 구분 기호인 출력 필드 구분 기호를 명시적으로 설정하고 각 필드 자체를 명시적으로 변환한 다음 필수 필드를 인쇄하고 OFS를 사용하여 구분합니다.

답변2

한 가지 방법은 다음과 같습니다.

awk -F \| -v OFS=, '{ NF--; for(i = NF-2; i <= NF; i++) $i = sprintf("%07.2f", $i) } 1' filename

관련 정보