배쉬 곱셈과 덧셈


18
for k in {0..49};
do
a=$(($((2*$k))+1));
echo $a;
done

안녕하세요, 세 번째 줄에 대한 단순화 된 표현이 필요합니다. 명령 대체를 사용하지 않는 표현 일 수 있습니다.


@ Theophrastus : 제안대로 잘 작동하지만 (()) 대신 expr을 사용하고 싶다면 어떻게해야합니까?
AVS

입니다 bash하지 C, 그래서 모두 제거 ;- 당신이 단일 라인을 작성하지 않는 한.
ott--


declare -i a; for k in {0..49}; do a=2*$k+1; echo $a; done
사이러스

1
옆으로 : $(( ... ))명령 대체가 아닌 산술 확장입니다.
dave_thompson_085

답변:


28

산술 확장 사용 :

for (( k = 0; k < 50; ++k )); do
  a=$(( 2*k + 1 ))
  echo "$a"
done

구식 expr유틸리티 사용 :

for (( k = 0; k < 50; ++k )); do
  a=$( expr 2 '*' "$k" + 1 )
  echo "$a"
done

사용 bc -l( -l수학 함수가 사용되지 않으므로이 경우 실제로 필요하지 않음) :

for (( k = 0; k < 50; ++k )); do
  a=$( bc -l <<<"2*$k + 1" )
  echo "$a"
done

하여 bc -l공동 처리 (는 background¹에서 계산 서비스의 일종처럼 행동)로 :

coproc bc -l

for (( k = 0; k < 50; ++k )); do
  printf "2*%d + 1\n" "$k" >&${COPROC[1]}
  read -u "${COPROC[0]}" a
  echo "$a"
done

kill "$COPROC_PID"

마지막으로 (논쟁 적으로) 깨끗해 보입니다 ksh93.

bc -l |&
bc_pid="$!"

for (( k = 0; k < 50; ++k )); do
  print -p "2*$k + 1"
  read -p a
  print "$a"
done

kill "$bc_pid"

¹ 이렇게하면 루프에서 많은 양의 입력을 처리해야하는 문제가 해결되었습니다. 처리에는 일부 부동 소수점 계산이 필요했지만 bc루프에서 몇 번 스폰 되는 것이 매우 느리다는 것이 입증되었습니다. 예, 다른 많은 방법으로 해결할 수 있었지만 지루했습니다 ...



5

let명령을 사용하여 계산을 강제 할 수 있습니다 .

let a="2*k+1"

$k이 구조 에서는 필요하지 않습니다 . 간단한 k일을 할 것입니다.


4
a=2whateverk+1현재 디렉토리에 파일이 있으면 실패합니다 . 게다가라는 파일이 있으면 명령 a=2+b[$(reboot)]k+1을 호출합니다 reboot. ((...))여기 ( ((a = 2 * k + 1))) 또는 POSIX 구문 을 사용하는 것이 가장 좋습니다 .a=$((2 * k + 1))
Stéphane Chazelas

우리는 그것을 인용 할 수 있습니다. let a="2*k+1"그것을 해결하기 위해.
Stephen Harris

2

아마도 필요한 산술 확장은 다음과 같습니다.

a=$(( 1+2*k ))

실제로 변수를 사용할 필요는 없습니다.

for k in {0..49}; do
    echo "$(( 1 + 2*k ))"
done

또는 계수 변수를 for ((…))루프 로 옮길 수 있습니다 .

for (( k=0;k<50;k++ )); do
    a=$(( 1+2*k ))
    printf '%s\n' "$a"
done

for ((…)) 루프

그리고이 경우 산술 확장도 for 루프 내부로 이동할 수 있습니다.

for (( k=0 ; a=1+2*k , k<50 ;  k++)); do
    printf '%s\n' "$a"
done

또는 배열의 모든 값을 얻으려면

for (( k=0 ; a[k]=1+2*k , k<49 ;  k++ )); do :; done
printf '%s\n' "${a[@]}"

공식 없음

그러나 산술 확장을 피하는 가장 짧은 방법은 변수를 두 번 증가시키는 것입니다.

for (( k=0,a=1 ; k<50 ;  k++,a++,a++ )); do
    printf '%s\n' "$a"
done

또는 더 간단하게 seq를 사용하십시오.

seq 1 2 100
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.