다음과 같은 붙여넣기 명령이 있습니다.
paste -d , file1.csv file2.csv file3.csv
file2.csv에는 다음과 같은 숫자가 포함되어 있습니다.
0.2
0.3339
0.111111
file2.csv의 값에 다음과 같이 소수점 이하 3자리가 포함되기를 원합니다.
0.200
0.334
0.111
값의 경우 다음과 같이 작동합니다.
printf "%.3f" "0.3339"
->0.334
그러나 이것은 file2.csv의 여러 값에 대해서는 작동하지 않습니다.
paste -d , file1.csv <(printf %s "%.3f" "$(< file2.csv)") file3.csv
어쩌면 좋은 해결책이 있을까요?
답변1
numfmt
여기서 유용해 보이는 GNU coreutils 도구 모음의 일부인 GNU Utilities라는 GNU 유틸리티가 있습니다 . 숫자 값의 형식을 지정할 수 있으며, 다음 명령은 형식 문자열 ("소수점 세 자리까지의 정밀도를 갖는 부동 소수점 값")을 file2.csv
사용하여 모든 값의 형식을 지정합니다. 형식화된 값은 표준 출력에 인쇄됩니다.printf
%.3f
$ numfmt --format=%.3f <file2.csv
0.200
0.334
0.112
보시다시피 기본적으로 "0부터 시작하는" 반올림을 사용하지만 다음을 사용하여 변경할 수 있습니다 --round=nearest
.
$ numfmt --format=%.3f --round=nearest <file2.csv
0.200
0.334
0.111
paste
다음과 같이 프로세스 대체를 사용하여 명령에 삽입 할 수 있습니다 .
paste -d , file1.csv <( numfmt --format=%.3f --round=nearest <file2.csv ) file3.csv
파일이 "단순"하지 않은 CSV인 경우, 즉 인용된 필드가 포함될 수 있는 경우 CSV 인식 도구를 사용해야 할 수도 있습니다.밀러( mlr
) 데이터 처리. 위의 두 번째 예는 Miller 표현식 numfmt
(형식 문자열 사용)의 함수를 사용하여 아래에서 다시 생성됩니다.fmtnum()
put
printf
$ mlr --csv -N put '$1 = fmtnum($1, "%.3f")' file2.csv
0.200
0.334
0.111
및 --csv
옵션을 사용하면 -N
Miller는 헤더 없는 CSV로 입력을 읽고 출력을 쓸 수 있습니다.
답변2
printf
거의 다 끝났습니다. 소수점 오른쪽에 제로 패딩을 알려주면 됩니다 .
$ cat 736678.txt
0.2
0.3339
0.111111
$ for value in $( cat 736678.txt ); do printf "%.3f\n" "$value"; done
0.200
0.334
0.111
형식 문자열은 %.3f
"이 지점 오른쪽에 정확히 소수점 세 자리가 있는 부동 소수점 숫자"를 의미합니다.
답변3
이를 사용 awk
하여 모든 읽기, 서식 지정 및 붙여넣기 작업을 수행할 수 있습니다.
LC_ALL=C awk '
{
getline f2 < "file2.csv"
getline f3 < "file3.csv"
printf "%s,%.3f,%s\n", $0, f2, f3
}' file1.csv
출력에서 원하는 만큼의 행을 얻을 수 있습니다 file1.csv
( 0.000
파일 2에 더 적은 행이 있으면 파일 3에 빈 문자열이 있음).
일부 구현 awk
(GNU 포함)은 변수가 환경에 존재할 때 입력 및 출력에서 로케일의 10진수 기본 문자를 존중합니다. 예를 들어, 프랑스어 또는 독일어 로케일에서는 십진수 기수 문자가 인식되지 않고 가비지로 처리되는 것으로 해석되어 CSV 형식을 깨는 출력을 얻게 됩니다.awk
POSIXLY_CORRECT
,
.
1.2e5
1
.2e5
1,000
따라서 위의 내용은 10진수 기수 문자가 있는 위치 LC_ALL=C
로 로케일을 수정합니다 .C
.