숫자가 공백으로 구분되는 변수 세트가 있습니다. 여기서 첫 번째 숫자는 공백으로 이어질 수도 있습니다. 예를 들면 다음과 같습니다.
VAR=" 2 1 34 3 2 "
이 숫자를 모두 더해야 해요. 가장 쉬운 방법은 숫자 사이의 모든 공백을 +
bc의 파이프 로 바꾸는 것입니다 .
for 루프, 붙여넣기 및 bc를 사용하여 수행할 수 있지만 더 쉬운 방법을 아는 사람이 있을까요? VAR
bash 내장 문자열 대체 기능을 사용하여 bash에서 직접 계산을 수행할 수 있을까요 ?
$ for i in $VAR;do echo $i;done|paste -sd+|bc
42
업데이트: 모든 제안 덕분에 마침내 배열을 사용하는 상당히 짧은 방법을 찾았습니다.
$ VAR=" 2 1 34 3 2 "
$ arr=( $VAR );echo "$((${arr[@]/%/+}0))"
42
$ VAR="$VAR -14"
$ arr=( $VAR );echo "$((${arr[@]/%/+}0))"
28
$
답변1
소스 문자열에 반복되는 공백과 선행/후행 공백이 포함되어 있습니다.
간단한 공간 변환은 +
실패합니다.
$ value=' 2 1 34 3 2 '
$ echo "${value// /+}"
++++++2+1++34+3++++2++++
반복되는 공백 모두 접기그리고선행/후행 공백을 제거하려면 따옴표가 없는 변수만 에코(또는 printf)하면 됩니다(IFS가 기본값이라고 가정).
value=$(echo $value)
echo "${value// /+}"
2+1+34+3+2
이는 bc에 제공될 수 있습니다.
$ echo "${value// /+}" | bc
42
원하는 경우 한 줄에 모든 내용:
value=$(echo $value); echo "${value// /+}" | bc
또는 sed
필터로 사용할 수도 있습니다(추가 변수는 없지만 속도가 느림).
echo $value | sed 's/ /+/g' | bc
이전 시도에서 <<<
문제가 발생했습니다.
$ ~/bin/b44sh -c 'value=" 2 1 34 3 2 ";sed "s/ /+/g" <<<$value'
++++++2+1++34+3++++2++++
버전 4.4부터 bash에서. 이전 버전에서는 다음과 같이 작동했습니다.
~/bin/b43sh -c 'value=" 2 1 34 3 2 ";sed "s/ /+/g" <<<$value'
2+1+34+3+2
bash(및 sed)의 모든 버전에서 다음을 수행할 수 있습니다(상당히 강력한 버전이지만 외부 유틸리티 호출 - sed
).
sed "s/ \+/+/g" <<<"0 $value 0" | tee /dev/tty | bc
0+2+1+34+3+2+0
42
순수한 쉘 솔루션(교체 ${//}
부분으로 bash, ksh 또는 zsh 필요)은 다음과 같습니다.
value=$(echo $value); bc <<<"${value// /+}
하나 더 있어요강한(가정 실행™) 및가지고 다닐 수 있는버전:
- IFS에 대한 변경 사항이 현재 셸에 영향을 미치지 않도록 합니다. 서브쉘을 사용하세요
(…)
. - IFS가 공백의 값을 나누는지 확인하십시오(IFS=" ").
- 따옴표 없이도 문자열이 확장되지 않는지 확인하십시오
*
(set -f). +
부품이 (IFS=+)로 연결되어 있는지 확인하십시오.
( IFS=" "; set -f; set -- $value; IFS=+; echo "$*" | bc; )
기능 버전 1 -
쉘이 이를 허용하지 않는 경우 local
더 느린 서브쉘을 사용하십시오. 양식
2 - 일부(POSIX에서는 정확함)는 따옴표 없이 사용하는 것에 대해 불평할 수 있습니다 $*
.
sum(){ local IFS=" "; set -f; set -- $*; IFS=+; echo "$*" | bc; }
다양한 방법으로 매개변수를 추가합니다.
$ value=" 2 1 34 3 2 "
$ sum "$value"
42
$ sum $value # beware of glob chars *, ? and [ and of odd IFS=123 settings
42
$ sum " 2 1 34 3 2 "
42
$ sum " 2" "1 " "34 3" " 2 "
42
$ var=23
$ sum " 2" "1 " "34 3" " 2 " "$var"
65
답변2
매개변수 확장을 사용합니다.
#!/bin/bash
VAR=" 2 1 34 3 2 "
shopt -s extglob # Enable the `+(...)` construct.
expression=${VAR#+(\ )} # Remove leading spaces.
expression=${expression%+(\ )} # Remove trailing spaces.
bc <<< ${expression//+(\ )/+} # Replace strings of spaces by pluses.
답변3
몇 가지 Perl 팁:
$ perl -lane '$t+=$_ for @F; print $t' <<<"$var"
42
또는
$ perl -pe 's/(\d)\s+(?=\d)/$1+/g' <<<"$var" | bc
42
또는
$ perl -lane 'print eval join "+", @F' <<<"$var"
42
또는 GNU sed
및 coreutils:
$ tr -s ' ' '+' <<<$var | sed 's/^+//; s/+$//' | bc
42
답변4
배시 스크립트:
$ v="2 4 7 10 3"
$ s=0
$ for i in $v
> do
> s=$((s+i))
> done
$ echo $s
26