변수와 관련된 수학 연산에서 소수를 파생하는 방법은 무엇입니까?

변수와 관련된 수학 연산에서 소수를 파생하는 방법은 무엇입니까?

SCALEFACTOR기본적으로 을 찾으려고 합니다 10000/(sum of 4th column in a file). 출력에서 ​​소수점을 어떻게 구하나요? 도움을 주셔서 미리 감사드립니다.

#!/bin/bash

FILES=/path/to/files/*;
for f in ${FILES}
do
    echo $f
    COLTOTAL="$(awk '{sum += $4} END {print sum}' $f)"
    echo "total: ${COLTOTAL}"
#    SCALEFACTOR=`expr 10^5 / $COLTOTAL`
    B=10000
    SCALEFACTOR=$((B / ${COLTOTAL}))
    SCALINGFACTOR=$(echo "100000 / $COLTOTAL" | bc -l
#    echo "scale=5; ${SCALEFACTOR}" | bc
    echo ${SCALEFACTOR}
    awk '{print($1"\t"$2"\t"$3"\t"$4 * ${SCALINGFACTOR})}' $f > $f"_normalized.txt"

done

답변1

for파일에 공백이 포함되어 있으면 루프가 구현되는 방식이 중단됩니다. for f in /path/to/files/*루프가 이해하는 방식으로 확장이 발생하기 때문에 변수 없이도 잘 작동합니다 for.

일반적으로 새 프로세스를 시작하면 리소스가 소비되므로 sum 인스턴스를 하나만 갖는 것이 더 좋으며 @jw013이 지적했듯이 sum은 부동 소수점 연산을 수행할 수 없기 awk때문에 셸 외부에서 나누기를 수행해야 합니다 .shbash

각 줄에서 작업하려면 파일의 끝을 알아야 하기 때문에 두 가지 옵션이 있습니다. 즉, 각 파일을 읽거나, 두 번째 읽기를 위해 각 줄을 저장하거나, 각 파일을 두 번 읽습니다. 대용량 파일을 메모리에 저장하는 것은 문제가 될 수 있으므로 두 번째 옵션을 선택했습니다.

for f in /path/to/files/*; do
  echo "$f"
  awk '
    NR == FNR {
      sum += $4;
      next;
    }
    FNR == 1 {
      print "total: " sum;
      SCALEFACTOR = 10000 / sum;
      print SCALEFACTOR;
    }
    {
      printf("%s\t%s\t%s\t%f\n", $1, $2, $3, $4 * SCALEFACTOR);
    }' "$f" "$f"

NR == FNR이는 총 레코드(줄) 번호가 현재 파일의 레코드 번호와 동일하다는 것을 의미합니다. 즉, 현재 파일이 첫 번째 파일에 있고 현재 작업이 합계를 결정하는 것임을 의미합니다. next다른 조항이 실행되는 것을 방지합니다. 그렇지 않고 두 번째로 파일의 첫 번째 줄을 읽으면 awk호출 사이에 수행한 작업을 수행합니다. 두 번째 읽기의 각 줄에 대해 4개의 항목을 인쇄하고 네 번째 항목은 지정한 대로 크기가 조정됩니다.

네 번째 항목에 표준 문자열 형식을 사용할 수 있습니다. 예를 들어 bc주석의 다섯 번째 수준은 %f다음과 같이 변경 됩니다.%.5f

답변2

(echo "scale=5"; echo "100000 / $COLTOTAL") | bc -l

관련 정보