[cmd_test@btjeon-naver ~]$ a="foo"
[cmd_test@btjeon-naver ~]$ echo "$a_file"
[cmd_test@btjeon-naver ~]$ echo "${a}_file"
foo_file
변수의 내용에 문자열 추가하려 할 때, 중괄호({}) 사용
[cmd_test@btjeon-naver ~]$ foo=
[cmd_test@btjeon-naver ~]$
[cmd_test@btjeon-naver ~]$ echo ${foo:-"substitute value if unset"}
substitute value if unset
[cmd_test@btjeon-naver ~]$ echo $foo
[cmd_test@btjeon-naver ~]$ foo=bar
[cmd_test@btjeon-naver ~]$ echo ${foo:-"substitute value if unset"}
bar
[cmd_test@btjeon-naver ~]$ echo $foo
bar
${parameter:-word} : parameter가 설정되어 있지 않거나(즉, 존재하지 않으면) 비어있다면, 이 확장 결과는 word의 값이 된다.
[cmd_test@btjeon-naver ~]$ foo=
[cmd_test@btjeon-naver ~]$ echo ${foo:="default value if unset"}
default value if unset
[cmd_test@btjeon-naver ~]$ echo $foo
default value if unset
[cmd_test@btjeon-naver ~]$ foo=bar
[cmd_test@btjeon-naver ~]$ echo ${foo:="default value if unset"}
bar
[cmd_test@btjeon-naver ~]$ echo $foo
bar
${parameter:=word} : 등호를 사용하면 word의 값이 parameter에 할당된다.
[cmd_test@btjeon-naver ~]$ foo=
[cmd_test@btjeon-naver ~]$ echo ${foo:?"parameter is empty"}
-bash: foo: parameter is empty
[cmd_test@btjeon-naver ~]$ echo $?
1
[cmd_test@btjeon-naver ~]$ foo=bar
[cmd_test@btjeon-naver ~]$ echo ${foo:?"parameter is empty"}
bar
[cmd_test@btjeon-naver ~]$ echo $?
0
${parameter:?word} : 물음표를 사용할 때 parameter가 설정되지 않거나 비어있다면 이 확장으로 오류가 발생하며 스크립트는 종료된다. 그리고 word의 값은 표준 출력으로 보내진다.
[cmd_test@btjeon-naver ~]$ foo=
[cmd_test@btjeon-naver ~]$ echo ${foo:+"substitute value if set"}
[cmd_test@btjeon-naver ~]$ foo=bar
[cmd_test@btjeon-naver ~]$ echo ${foo:+"substitute value if set"}
substitute value if set
[cmd_test@btjeon-naver ~]$ echo $foo
bar
${parameter:+word} : 더하기를 사용할 때 parameter가 설정되지 않거나 비어있다면 이 확장은 아무런 결과를 표시하지 않는다. 만약 parameter가 비어있지 않다면 parameter는 word의 값으로 대체된다. 하지만 parameter의 값은 변하지 않는다.
[cmd_test@btjeon-naver ~]$ echo ${!BASH*}
BASH BASHOPTS BASHPID BASH_ALIASES BASH_ARGC BASH_ARGV BASH_CMDS BASH_COMMAND BASH_COMPLETION_COMPAT_DIR BASH_LINENO BASH_REMATCH BASH_SOURCE BASH_SUBSHELL BASH_VERSINFO BASH_VERSION
[cmd_test@btjeon-naver ~]$ echo ${!BASH@}
BASH BASHOPTS BASHPID BASH_ALIASES BASH_ARGC BASH_ARGV BASH_CMDS BASH_COMMAND BASH_COMPLETION_COMPAT_DIR BASH_LINENO BASH_REMATCH BASH_SOURCE BASH_SUBSHELL BASH_VERSINFO BASH_VERSION
${!prefix*}, ${!prefix@} : 이 확장은 prefix로 시작되는 이미 존재하는 변수의 이름을 반환한다. (두 형식이 동일하게 동작한다.)
[cmd_test@btjeon-naver ~]$ foo="This string is long."
[cmd_test@btjeon-naver ~]$ echo "'$foo' is ${#foo} characters long."
'This string is long.' is 20 characters long.
${#parameter} : 이 확장은 parameter가 포함된 문자열의 길이로 확장된다.
[cmd_test@btjeon-naver ~]$ foo="This string is long."
[cmd_test@btjeon-naver ~]$ echo ${foo:5}
string is long.
[cmd_test@btjeon-naver ~]$ echo ${foo:5:6}
string
[cmd_test@btjeon-naver ~]$ echo ${foo: -5}
long.
[cmd_test@btjeon-naver ~]$ echo ${foo: -5:2}
lo
${parameter:offset}, ${parameter:offset:length} : 이 확장은 parameter에 포함된 문자열의 일부를 추출하기 위해 사용된다. offset에 위치한 문자부터 시작해서 length를 명시하지 않으면 문자열 끝까지 추출한다.
만약 offset 값이 음수이면 문자열의 일부분이 아닌 끝부분부터 시작하라는 것을 의미한다.${parameter:-word} 확장과 혼동을 막기 위해 음수 값은 반드시 앞에 공백을 두어야 한다.
[cmd_test@btjeon-naver ~]$ foo=file.txt.zip
[cmd_test@btjeon-naver ~]$ echo ${foo#*.}
txt.zip
[cmd_test@btjeon-naver ~]$ echo ${foo##*.}
zip
[cmd_test@btjeon-naver ~]$ echo ${foo%.*}
file.txt
[cmd_test@btjeon-naver ~]$ echo ${foo%%.*}
file
${parameter:#pattern}, ${parameter:##pattern} : 이 확장은 매개변수가 가진 문자열에서 pattern(와일드카드 패턴)에 정의된 내용으로 시작하는 부분을 제거한다. # 형식은 최단 길이로 일치하는 것을 제거하고 ## 형식은 최장 길이로 일치하는 것을 제거한다.
${parameter:%pattern}, ${parameter:%%pattern} : #, ##와 동일하지만 문자열의 시작이 아닌 끝에서부터 제거한다.
[cmd_test@btjeon-naver ~]$ foo=JPG.JPG
[cmd_test@btjeon-naver ~]$ echo ${foo/JPG/jpg}
jpg.JPG
[cmd_test@btjeon-naver ~]$ echo ${foo//JPG/jpg}
jpg.jpg
[cmd_test@btjeon-naver ~]$ echo ${foo/#JPG/jpg}
jpg.JPG
[cmd_test@btjeon-naver ~]$ echo ${foo/%JPG/jpg}
JPG.jpg
${parameter/pattern/string}, ${parameter//pattern/string}, ${parameter/#pattern/string}, ${parameter/%pattern/string} :
이 확장은 parameter의 내용을 치환한다. 와일드 카드 pattern과 일치하는 텍스트를 발견하면 string의 내용으로 대치된다.
- / 형식은 일치하는 첫 부분만 대체한다.
- // 형식은 일치하는 모든 부분을 대체한다.
- /# 형식은 문자열의 시작 부분에서 일치하는 첫 부분만 대체한다.
- /% 형식은 문자열의 끝 부분에서 일치하는 첫 부분만 대체한다.
[cmd_test@btjeon-naver ~]$ vi longest_word3.sh
------------------------------------------------------------------------------------------
#!/bin/bash
# longest-word3 : find longest string in a file
for i; do
if [[ -r $i ]]; then
max_word=
max_len=0
for j in $(strings $i); do
len=${#j}
if (( len > max_len )); then
max_len=$len
max_word=$j
fi
done
echo "$i: '$max_word' ($max_len characters)"
fi
done
------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ time ./longest_word2.sh dirlist-usr-bin.txt
dirlist-usr-bin.txt: 'abrt-action-check-oops-for-hw-error' (36 characters)
real 0m1.405s
user 0m0.920s
sys 0m0.481s
[cmd_test@btjeon-naver ~]$ time ./longest_word3.sh dirlist-usr-bin.txt
dirlist-usr-bin.txt: 'abrt-action-check-oops-for-hw-error' (35 characters)
real 0m0.011s
user 0m0.008s
sys 0m0.003s
$(echo $j | wc -c) 명령을 ${#j} 매개변수 확장으로 바꾼 후 time 명령어를 사용하여 두 버전의 효율성을 비교하였다. 이전 스크립트는 1.405초, 바꾼 스크립트는 0.011초 걸렸다.
[cmd_test@btjeon-naver ~]$ echo $(( 5 / 2 ))
2
[cmd_test@btjeon-naver ~]$ echo $(( 5 % 2 ))
1
[cmd_test@btjeon-naver ~]$ vi modulo.sh
------------------------------------------------------------------------------------------
#!/bin/bash
# modulo : demonstrate the modulo operator
for ((i - 0; i <= 20; i = i + 1)); do
remainder=$((i % 5))
if (( remainder == 0 )); then
printf "<%d> " $i
else
printf "%d " $i
fi
done
------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./modulo.sh
<0> 1 2 3 4 <5> 6 7 8 9 <10> 11 12 13 14 <15> 16 17 18 19 <20>
기본 연산자 사용 예제
[cmd_test@btjeon-naver ~]$ foo=1
[cmd_test@btjeon-naver ~]$ echo $((foo++))
1
[cmd_test@btjeon-naver ~]$ echo $foo
2
[cmd_test@btjeon-naver ~]$ foo=1
[cmd_test@btjeon-naver ~]$ echo $((++foo))
2
[cmd_test@btjeon-naver ~]$ echo $foo
2
[cmd_test@btjeon-naver ~]$ vi modulo2.sh
--------------------------------------------------------------------------------------
#!/bin/bash
# modulo2 : demonstrate the modulo operator
for ((i - 0; i <= 20; ++i)); do
if (( (i % 5) == 0 )); then
printf "<%d> " $i
else
printf "%d " $i
fi
done
printf "\n"
--------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./modulo2.sh
<0> 1 2 3 4 <5> 6 7 8 9 <10> 11 12 13 14 <15> 16 17 18 19 <20>
대입 연산자 사용 예제
[cmd_test@btjeon-naver ~]$ for ((i=0;i<8;++i)); do echo $((1<<i)); done
1
2
4
8
16
32
64
128
왼쪽 비트 연산자를 사용하여 2의 배수를 생성하는 예제
[cmd_test@btjeon-naver ~]$ if ((1)); then echo "true"; else echo "false"; fi
true
[cmd_test@btjeon-naver ~]$ if ((0)); then echo "true"; else echo "false"; fi
false
[cmd_test@btjeon-naver ~]$ a=0
[cmd_test@btjeon-naver ~]$ ((a<1?++a:--a))
[cmd_test@btjeon-naver ~]$ echo $a
1
[cmd_test@btjeon-naver ~]$ ((a<1?++a:--a))
[cmd_test@btjeon-naver ~]$ echo $a
0
[cmd_test@btjeon-naver ~]$ ((a<1?(a+=2):(a-=2)))
[cmd_test@btjeon-naver ~]$ echo $a
2
[cmd_test@btjeon-naver ~]$ ((a<1?(a+=2):(a-=2)))
[cmd_test@btjeon-naver ~]$ echo $a
0
논리 연산자 사용 예제
[cmd_test@btjeon-naver ~]$ vi arith-loop.sh
---------------------------------------------------------------------------------------------
#!/bin/bash
# arith-loop : script to demonstrate arithmetic operators
finished=0
a=0
printf "a\ta**2\ta**3\n"
printf "=\t====\t====\n"
until ((finished)); do
b=$((a**2))
c=$((a**3))
printf "%d\t%d\t%d\n" $a $b $c
((a<10?++a:(finished=1)))
done
---------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./arith-loop.sh
a a**2 a**3
= ==== ====
0 0 0
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
산술 연산자를 이용해 간단한 계산 표를 생성하는 스크립트
[cmd_test@btjeon-naver ~]$ vi foo.bc
------------------------------------------------------------------------------------------
/* A very simple bc script */
2 + 2
------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ bc foo.bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
4
quit
bc 프로그램 사용 예제
[cmd_test@btjeon-naver ~]$ bc -q
2 + 2
4
quit
bc 프로그램 대화식 사용 예제
[cmd_test@btjeon-naver ~]$ bc < foo.bc
4
[cmd_test@btjeon-naver ~]$ bc <<< "2+2"
4
표준 입력을 통해 bc 스크립트를 전달하는 것도 가능하다.
[cmd_test@btjeon-naver ~]$ vi loan-calc.sh
---------------------------------------------------------------------------------------------
#!/bin/bash
# loal-calc : script to calculate monthly loan payments
PROGNAME=$(basename $0)
usage () {
cat <<- EOF
Usage: $PROGNAME PRINCIPAL INTEREST MONTHS
Where:
PRINCIPAL is the amount of the loan.
INTEREST is the APR as a number (7% = 0.07).
MONTHS is the length of the loan's term.
EOF
}
if (($# != 3)); then
usage
exit 1
fi
principal=$1
interest=$2
months=$3
bc <<- EOF
scale = 10
i = $interest / 12
p = $principal
n = $months
a = p * ((i * ((1 + i) ^ n)) / (((1 + i) ^ n) - 1))
print a, "\n"
EOF
---------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./loan-calc.sh 135000 0.0775 180
1270.7222490000
bc 명령어를 사용하여 월별 상환금을 계산하는 예제이다. 결과에 대한 소수점 정밀도를 bc 스크립트의 특별한 scale 변수로 설정하였다.
출처 : 리눅스 커맨드라인 완벽 입문서
'IT일반 > Linux' 카테고리의 다른 글
VI editor reference (0) | 2022.06.21 |
---|---|
Command Line - 배열 (0) | 2022.06.18 |
Command Line - 흐름 제어 : for 루프 (0) | 2022.06.13 |
Command Line - 위치 매개변수 (0) | 2022.06.08 |
Command Line - 흐름 제어 : Case 분기 (0) | 2022.06.07 |