네트워크 스트림에서 데이터베이스를 스크립팅하려고 합니다. 과도하게 sed된 후 네트워크 스트림은 file.db라는 이름의 3개 열 파일을 삭제합니다.
123.123.123.123,컴퓨터 이름,110000103e21cc4
123.123.123.124,컴퓨터2,11000010416200f
123.123.123.1,컴퓨터3,110000106eb3f43
나는이 gawk 명령을 아무 소용없이 사용하려고했습니다.
gawk 'BEGIN {FS=OFS=","} {print $1,$2,strtonum("0x"$3)}' file.db
위의 출력은 다음과 같습니다
123.123.123.123,컴퓨터 이름,76561198025415874
123.123.123.124,컴퓨터2,76561198028824592
123.123.123.1,컴퓨터3,76561198076346171
그러나 출력은 다음으로 변환되어야 합니다.
123.123.123.123,컴퓨터 이름,76561198025415876
123.123.123.124,컴퓨터2,76561198028824591
123.123.123.1,컴퓨터3,76561198076346179
출력이 항상 약간씩 꺼져 있으므로 시스템의 일부 라이브러리가 올바르지 않다고 가정합니다... 그런데 이것은 이것이 실행 중인 임베디드 시스템이고 변환할 수 있다는 것을 알고 있습니다. 원인은 bc, printf, 기타 등등
어떻게 하면 이 작업을 수행할 수 있나요?
답변1
변환된 값을 배정밀도 부동 소수점으로 내부적으로 gawk
저장하므로 작은 불일치는 부동 소수점 값에 상속된 반올림 오류일 뿐입니다. 정확한 결과를 얻으려면 gawk
숫자 처리를 임의의 정밀도 숫자를 지원하는 다른 명령(예: )으로 아웃소싱해야 합니다 bc
.
그러나 현재 gawk
구문으로는 gawk 내에서 복잡한 쉘 명령줄 구문 분석을 수행하는 것이 불가능하므로 먼저 쉘 스크립트 도우미가 필요합니다. 이름을 지정해 보겠습니다 bc.sh
.
#!/bin/bash
echo -e "ibase=16\n$1" | bc -q
이 스크립트는 ibase=16
첫 번째 인수(16진수)를 에 공급하여 해당 십진수를 출력합니다 bc
. bc
그러면 gawk
다음과 같이 호출됩니다.
gawk 'BEGIN {FS=OFS=","} { "./bc.sh " toupper($3) | getline b; print $1,$2,b}' file.db
이는 gawk
대문자 $3( bc
소문자 16진수 값을 지원하지 않음)를 사용하여 쉘 스크립트를 호출하고, 결과를 b
변수에 저장하고, 모든 인수를 한 번에 인쇄하도록 지시합니다.
./bc.sh
큰따옴표 안에 공백이 추가되어야 한다는 점에 주의하세요 ./bc.sh110000103E21CC4
. 그렇지 않으면 .
답변2
나는 이것을 되돌아보고 내가 이 일을 하게 된 방식은 다음과 같습니다.
Convert12345678.sh와 같은 bash 스크립트 만들기
#!/opt/bin/bash
(echo -e "ibase=16\nobase=0A" ; echo $1 | tr 'a-z' 'A-Z') | bc | tr "\n" " " | sed 's/\ //g'
그런 다음 op에서와 같이 내가 필요한 모든 것을 gawk에서 (그 이후로 그 프로그램을 크게 수정했습니다) 이런 것이었으며 이 프로그램을 파이프했지만 파일에서 시연하겠습니다.
gawk -F, '{printf("%s,%s,",$1,$2)};{system("/files/convert12345678 "$3)};{printf("\n")}' file.db
나는 bash 스크립트에서 새 줄을 제거하는 방식으로 이 작업을 수행했습니다. 왜냐하면 솔직히 나중에 스크립트 실행 배치를 옮겼기 때문입니다. 이렇게 하면 내가 원하지 않는 한 변환 직후 출력에 개행 문자가 삽입되지 않을 것입니다. printf