다음과 같은 데이터가 있습니다.
cat file
(4567.99,5678.98)
(5678.33,6734.34)
내가 원하는 출력은 다음과 같습니다.
(45679900 56789800)
(56783300 67343400)
소수점을 취소하여 8자리로 만들고, 사이에 공백이 있도록 쉼표 기호를 제거하고 싶습니다.
awk
명령을 사용하는 방법? sed
그것도 괜찮습니다.
답변1
awk를 사용하세요:
awk -F'[(),]' '{ printf( "(%d %d)\n", $2 * 10000, $3 * 10000 ); }' file
답변2
sed -e 's/,/ /' -e 's/\.\(..\)/\100/g'
답변3
TxR앗 매크로: 실제로는 입력된 작업으로 이 작업을 수행할 수 있습니다. 데이터를 부동 소수점 값으로 가져와 가장 가까운 정수로 반올림하고 100을 곱하고 정수로 변환합니다.
그러나 잠시 멈추고 생각해 보십시오. 값이 너무 커서 가장 가까운 정수로 잘릴 수 없다면 임의로 큰 값에 대해서는 좋지 않은 생각일 수 있습니다. 텍스트상으로 이렇게 하는 것이 맞습니다.
$ txr -e '(awk (:begin (set ft #/\d+.\d+/))
((mf tofloat floor toint (* 100))))'
(4567.99, 123.45, junk 3.1415, 1.0 ...) x
456700 12300 300 100
변수 ft
는 새로운 기능입니다. 클래식 Awk에는 이에 상응하는 기능이 없습니다. (필드 구분 기호) fs
와 같은 것은 " 필드 토큰화"를 의미합니다. 이는 필드 간의 불일치를 무시하고 필드를 식별하고 추출하는 데 사용되는 정규식을 지정합니다.FS
ft
아이러니하게도
ft
Awk의 기본 필드 구분 기호의 의미는 직접적으로 표현될 수 있습니다. 선행 및 후행 줄 바꿈과 공백은 레코드에서 잘리고 하나 이상의 줄 바꿈이나 공백으로 구분됩니다. 이는 단순히 다음과 정확히 동일합니다.적극적으로필드를 공백이 아닌 것으로 구성된 토큰으로 인식합니다! Awk에 변수가 있으면 단일 공백과 동일할 때 적용되는 특별한 트릭이FT
필요하지 않습니다FS
. 기본값은FS
설정되지 않고 대신FK
regex로 설정될 수 있습니다[ \t\n]+
.
ft
우리는 숫자를 식별하고, 소수점을 강제하고, 숫자를 강제하는 간단한 방법을 사용합니다 . 선행 기호도 없고 선택 사항도 없습니다.
매크로 mf
("필드 매핑")는 각 필드를 작업 파이프라인에 넣습니다. 먼저 이 tofloat
함수는 문자열을 부동 소수점으로 변환합니다. 그런 다음 floor
음의 무한대 방향으로 가장 가까운 정수로 자릅니다. toint
inger로 돌아가서 (* 100)
추가 인수를 취하고 그 결과를 곱하는 함수 to의 부분 적용을 표현해 보겠습니다. 이 부분 적용 구문은 인수가 암시적으로 구문(TXR Lisp 명시적으로 부분 적용 연산자)으로 처리된다는 사실을 따릅니다.*
100
100
mf
op
mf
결과가 아닌 값이 반환되므로 기본 nil
작업은 (prn)
업데이트된 필드의 인쇄를 시작합니다 . 이 인쇄는 rec
업데이트된 필드를 단일 공백 문자로 구성된 기본 필드와 ofs
연결하여 재구성 되며 출력은 ors
기본적으로 개행 문자로 설정됩니다.
이는 부동 소수점 수학에 의존하지 않고 수치적으로 계산을 수행하는 방법입니다. 기본적으로 동일한 정규식을 사용하여 필드를 추출할 수 있지만 여전히 텍스트인 동안 점을 제거할 수 있습니다. 그런 다음 정수로 이동하여 잘린 정수 나누기와 곱셈을 사용합니다.
$ txr -e '(awk (:begin (set ft #/\d+.\d+/))
((mf (remq #\.) toint (trunc @1 100) (* 100))))'
이 언어에서는 정수가 임의로 커질 수 있으므로 이 솔루션은 매우 큰 숫자에 대한 문제를 나타내지 않지만 텍스트 처리를 최소화합니다.
답변4
awk '{gsub(/\./,"")sub(/,/," "); print $1"00",$2}' file
(45679900 567898)
(56783300 673434)