좋아, 그래서 나는 내 것을 좋아 awk
하지만 네, 정밀도 문제가 있고 불행히도 이라는 다중 정밀도 확장 프로그램을 설치하는 쉬운 방법이 없습니다 gawkextlib
.
내가 하고 있는 일은 다음 문제를 해결하는 것입니다.로잘린드 정보쉘 싱글 라이닝을 사용합니다. 나는 웹사이트에서 설정한 5분의 제한 시간 내에 DNA/RNA 가닥에 대해 필요한 계산을 수행하기 위해 이러한 쉘 명령문을 사용하는 것이 어렵지 않다는 것을 발견했습니다.
어쨌든 나는 이 문제에 봉착했지만, 나는 항상 Linux 도구에 대한 지식을 향상시키고 싶습니다. 이 경우에는 bc
에서 전화 해야 합니다 awk
.
명령은 다음 bc
과 같아야 합니다.
bc <<< "scale=1000; $1/$2"
내가 작업 중인 텍스트의 두 열은 $1
와 입니다 .$2
awk
이 awk
명령은 내가 작성한 일부 셸 함수에서 파생되었습니다.
nucleic-line () {
sed 's/\(.\)/\1\n/g' < $@
}
gc-numeric-count () {
n=$(nucleic-line $@ | wc -l)
m=$(nucleic-line $@ | grep -v "[AT]" | wc -l)
echo $m $n
}
export -f gc-numeric-count
column-percent-count () {
for f in $@; do gc-numeric-count $f; done | awk '{a = $1/$2 | print a * 100}'
}
내 목적에 비해 awk '{a = $1/$2 | print a * 100}'
정확하지 않습니다 . 구아닌과 시토신의 정확한 비율을 얻지만 awk
제공할 수 있는 것 보다 더 많은 소수 자릿수가 필요합니다 . 내가 말했듯이 불행히도 설치할 수 없습니다 . gawkextlib
임의의 정밀도가 필요하므로 bc
.awk
그렇다면 및 bc
에 대한 명령을 사용 하려면 마지막 표현식의 마지막 줄을 어떻게 수정해야 합니까 ?$1
$2
답변1
문제는 쉘을 프로그래밍 언어가 아닌 것으로 취급한다는 것입니다. 쉘은 무엇보다도 명령줄 해석기입니다. 쉘 스크립트는 스크립트입니다. 문제의 논리와 알고리즘을 구현하기 위해 쉘 구문을 사용한다면 잘못된 방향으로 가고 있는 것입니다.
코드에 인용되지 않은 변수와 같은 명백한 문제가 있습니다. 그러나 전체적으로 A와 T 이외의 파일에서 문자의 비율을 찾기 위해 너무 많은 명령을 실행하는 것은 (셸은 프로그래밍 언어가 아니라 명령을 실행하기 위한 도구이기 때문에) 추한 느낌입니다.
또한 awk는 내부적으로 64비트 부동 소수점 숫자를 사용합니다. 이보다 더 많은 정확성이 필요하다고 확신하시나요? 만약 이 숫자가 이것보다 더 정확한 것에 사용된다면, 이것을 사용할 수는 없을까요?무엇모든 일을 합니까?
귀하의 질문에 대답하려면 다음을 수행하십시오.
$ echo 1 3 | awk -vRS= '{("echo scale=300\\;" $1 "/" $2 "|bc -l") | getline; print}'
.3333333333333333333333333333333333333333333333333333333333333333333\
33333333333333333333333333333333333333333333333333333333333333333333\
33333333333333333333333333333333333333333333333333333333333333333333\
33333333333333333333333333333333333333333333333333333333333333333333\
33333333333333333333333333333
그러나 이것이 얼마나 무의미한지 쉽게 알 수 있습니다. awk는 각 입력 줄에 대해 쉘과 두 개의 명령을 실행하고 출력을 읽고 다시 인쇄합니다. 심지어 쉘도 모든 소란 없이 꽤 좋은 작업을 수행할 수 있습니다.
여전히 awk를 사용하고 싶다면 약간 덜 어리석은 방법은 다음과 같습니다.
echo 1 3 | awk 'BEGIN{print "scale=300"}{print $1"/"$2}' | bc
그 때에는 하나씩만 awk
주문이 들어오게 됩니다 bc
.
나에게는 실제 프로그래밍 언어(Perl, Ruby, Python이 떠오른다)가 필요하다는 것이 분명합니다. 쉘 스크립트에서 프로그래밍 언어의 인터프리터를 호출할 수 있지만 한 번만 호출할 수 있습니다. 단 한 번의 호출만으로 전체 작업을 완료할 수 있습니다.
답변2
스크립트의 나머지 부분은 확실하지 않습니다. (반환 값에 의존하는지 모르겠습니다.$m $n다른 곳) - 이것을 고려해 보셨나요?
gc-numeric-count () {
n=$(nucleic-line $@ | wc -l)
m=$(nucleic-line $@ | grep -v "[AT]" | wc -l)
echo "scale=1000;${m}/${n"}
}
export -f gc-numeric-count
column-percent-count () {
for f in $@; do gc-numeric-count $f | bc -l; done
}
답변3
변수 전달에는 아무런 문제가 없습니다. 또한 GNU dc(bc에 포함됨)는 임베디드 컴퓨팅, 더 적은 파이프라인 및 백폴리싱에 훨씬 쉽습니다.
print '355 113' | awk -vRS='' '{"dc -e \"1000k"$1" "$2"/pq\"" | getline; print; close(dc)}
Stephane의 의견에 동의합니다. Shell은 단서 작업을 수행하고 awk는 형식 지정 작업을 수행하며 계산은 dc에서 수행해야 합니다.