좋다여기나는파일.csv따옴표 안의 숫자:
"0.2"
"0.3339"
"0.111111"
숫자를 소수점 세 자리까지 반올림하려면 다음 솔루션이 효과적입니다.
printf "%.03f\n" $(sed 's/\"//g' file.csv)
sed 's/\"//g' file.csv
하지만 이제는 변수로 저장하고 싶습니다.
var_sed=$(sed 's/\"//g' file.csv);
printf "%.03f\n" ${var_sed}
작동하지 않습니다. 출력은 다음과 같습니다
zsh: bad math expression: operator expected at `0.3339\n0.1...'
0.000
그래서 문제 var_sed
는 .\n
printf "%.03f\n"
내가 아는 유일한 해결책은 다음과 같습니다.
var_sed=$(sed 's/\"//g' file.csv);
printf "%.03f\n" $(echo ${var_sed})
- 어쩌면 더 깨끗한 방법이 있을 수도 있습니다.
printf "%.03f\n"
또한 다음과 같은 기능을 추가하고 싶습니다 .
printf_function () { printf "%.03f\n" $1;}
하지만 이것은 작동하지 않습니다.
printf_function () { printf "%.03f\n" $1;};
var_sed=$(sed 's/\"//g' file.csv);
printf_function ${var_sed}
작동하지 않습니다 printf_function $(echo ${var_sed})
.
______________________________________________________________
파일을 변수에 저장하려는 이유는 무엇입니까? ______________________________________________________________
sed
문제는 실제로 명령을 함수에 넣고 싶다는 것입니다 . 죄송합니다. 문제를 단순화하기 위해 변수로 만들었습니다.
내 스크립트는
sed_01 () { sed 's/\"$// ; s/^\"// ; s/something_else//g' $1;};
printf_03 () { printf "%.03f\n" $1;};
printf_03 "$(sed_01 file.csv)"
아래 설명에서 언급했듯이 bash에서 작동합니다.
산출:
"0.200"
"0.334"
"0.111"
하지만 zsh에서는산출:예:
printf_03: bad math expression: operator expected at `0.3339\n0.1...'
0.000
답변1
printf "%.03f\n" $(sed 's/\"//g' file.csv) var_sed=$(sed 's/\"//g' file.csv); printf "%.03f\n" ${var_sed}
이는 숫자를 별도의 인수로 사용하는 토큰화에 의존합니다 printf
. 문제는 zsh가 과거의 어리석은 잔재로 자동 토큰화를 포기했으며 변수 확장을 위해 이를 수행하지 않는다는 것입니다. 그러나 어떤 이유에서든 명령 대체를 위해 이 작업을 수행합니다.
명령 대체에서 일반 스칼라 변수에 할당할 때 분할도 없으므로 출력의 줄 바꿈이 sed
변수에 저장됩니다.
이것이 바로 코드에서 명령 대체를 사용할 수 있지만 중간 변수는 사용할 수 없는 이유입니다.
변수의 값을 먼저 로드해야 하는 경우(단순히 인쇄용으로 수행하는 것이 아닌 경우) 다음을 고려하십시오.배열(zsh)에 저장합니다.:
lines=("${(f)$(sed 's/\"//g' file.csv)}")
printf "%.03f\n" $lines
readarray
Bash에서는 /를 사용할 수 있습니다 mapfile
.
mapfile -t lines < <(sed 's/\"//g' file.csv)
printf "%.03f\n" "${lines[@]}"
또는 둘 중 하나에 주로 적용되는 것을 원한다면 다시 단어 분사에 의존해야 합니다.
lines=( $(sed 's/\"//g' file.csv) )
printf "%.03f\n" "${lines[@]}"
괄호에 주목하십시오. 배열을 할당하여 단어 분리가 다시 발생합니다. ("주요"에는 동작에 영향을 미치는 수정에 대한 일반적인 경고가 포함되며 IFS
파일 이름 글로빙도 발생합니다.)
그렇다면 다시 AWK를 사용하여 이와 같은 작업을 수행하는 것이 더 쉬울 수도 있습니다.
$ awk '{gsub(/"/, ""); printf "%.03f\n", $1}' file.csv
0.200
0.334
0.111