bash - 변수의 합계

bash - 변수의 합계

숫자가 공백으로 구분되는 변수 세트가 있습니다. 여기서 첫 번째 숫자는 공백으로 이어질 수도 있습니다. 예를 들면 다음과 같습니다.

VAR=" 2 1  34 3    2 "

이 숫자를 모두 더해야 해요. 가장 쉬운 방법은 숫자 사이의 모든 공백을 +bc의 파이프 로 바꾸는 것입니다 .

for 루프, 붙여넣기 및 bc를 사용하여 수행할 수 있지만 더 쉬운 방법을 아는 사람이 있을까요? VARbash 내장 문자열 대체 기능을 사용하여 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

관련 정보