수색…


소개

$ 문자는 매개 변수 확장, 명령 대체 또는 산술 확장을 소개합니다. 확장 할 매개 변수 이름 또는 기호는 중괄호로 묶을 수 있습니다.이 중괄호는 선택적 요소이지만 확장 될 변수가 이름 바로 뒤에있는 문자에서 보호되어 이름의 일부로 해석 될 수 있습니다.

Bash User Manual 에서 더 많은 것을 읽으십시오.

통사론

  • $ {parameter : offset} # 오프셋에서 시작하는 부분 문자열
  • $ {parameter : offset : length} # offset에서 시작하는 길이 "length"의 부분 문자열
  • $ {# parameter} # 매개 변수의 길이
  • $ {parameter / pattern / string} # 처음 나타나는 패턴을 string으로 대체합니다.
  • $ {parameter // pattern / string} # 모든 패턴을 문자열로 대체합니다.
  • $ {parameter / # pattern / string} # pattern이 처음에있는 경우 패턴을 string으로 대체합니다.
  • $ {parameter / % pattern / string} # 패턴이 끝 부분에 있으면 패턴을 문자열로 바꿉니다.
  • $ {parameter # pattern} # 매개 변수의 시작 부분에서 패턴의 가장 짧은 일치를 제거합니다.
  • $ {parameter ## pattern} # 매개 변수의 시작 부분에서 패턴의 가장 긴 일치를 제거합니다.
  • $ {parameter % pattern} # 매개 변수의 끝에서 패턴의 가장 짧은 일치를 제거합니다.
  • $ {parameter %% pattern} # 매개 변수의 끝에서 패턴의 가장 긴 일치를 제거합니다.
  • $ {parameter : -word} # 매개 변수가 unset / undefined 인 경우 단어로 확장합니다.
  • $ {parameter : = word} # 매개 변수 unset / undefined 및 매개 변수 설정시 단어로 확장
  • $ {매개 변수 : + word} # 매개 변수가 설정 / 정의 된 경우 단어로 확장

하위 문자열 및 하위 배열

var='0123456789abcdef'

# Define a zero-based offset
$ printf '%s\n' "${var:3}"
3456789abcdef

# Offset and length of substring
$ printf '%s\n' "${var:3:4}"
3456
4.2
# Negative length counts from the end of the string
$ printf '%s\n' "${var:3:-5}"
3456789a

# Negative offset counts from the end
# Needs a space to avoid confusion with ${var:-6}
$ printf '%s\n' "${var: -6}"
abcdef

# Alternative: parentheses
$ printf '%s\n' "${var:(-6)}"
abcdef

# Negative offset and negative length
$ printf '%s\n' "${var: -6:-5}"
a

매개 변수가 위치 매개 변수 이거나 아래 첨자 배열요소 인 경우에도 동일한 확장이 적용됩니다.

# Set positional parameter $1
set -- 0123456789abcdef

# Define offset
$ printf '%s\n' "${1:5}"
56789abcdef

# Assign to array element
myarr[0]='0123456789abcdef'

# Define offset and length
$ printf '%s\n' "${myarr[0]:7:3}"
789

유사한 확장이 오프셋이 단일 기반 인 위치 매개 변수에 적용됩니다.

# Set positional parameters $1, $2, ...
$ set -- 1 2 3 4 5 6 7 8 9 0 a b c d e f

# Define an offset (beware $0 (not a positional parameter)
# is being considered here as well)
$ printf '%s\n' "${@:10}"
0
a
b 
c
d
e
f

# Define an offset and a length
$ printf '%s\n' "${@:10:3}"
0
a
b

# No negative lengths allowed for positional parameters
$ printf '%s\n' "${@:10:-2}"
bash: -2: substring expression < 0

# Negative offset counts from the end
# Needs a space to avoid confusion with ${@:-10:2}
$ printf '%s\n' "${@: -10:2}"
7
8

# ${@:0} is $0 which is not otherwise a positional parameters or part
# of $@
$ printf '%s\n' "${@:0:2}"
/usr/bin/bash
1

하위 문자열 확장은 인덱싱 된 배열 과 함께 사용할 수 있습니다.

# Create array (zero-based indices)
$ myarr=(0 1 2 3 4 5 6 7 8 9 a b c d e f)

# Elements with index 5 and higher
$ printf '%s\n' "${myarr[@]:12}"
c
d
e
f

# 3 elements, starting with index 5
$ printf '%s\n' "${myarr[@]:5:3}"
5
6
7

# The last element of the array
$ printf '%s\n' "${myarr[@]: -1}"
f

매개 변수의 길이

# Length of a string
$ var='12345'
$ echo "${#var}"
5

그것은 문자 의 길이가 반드시 바이트 수 (대부분의 문자가 2 바이트 이상으로 인코딩되는 UTF-8과 같음) 또는 글립 / 글자 수 (일부는 문자의 조합), 또는 반드시 디스플레이 너비와 동일하지는 않습니다.

# Number of array elements
$ myarr=(1 2 3)
$ echo "${#myarr[@]}"
3

# Works for positional parameters as well
$ set -- 1 2 3 4
$ echo "${#@}"
4

# But more commonly (and portably to other shells), one would use
$ echo "$#"
4

알파벳 문자의 대 / 소문자 변경

4.0

대문자하려면

$ v="hello"
# Just the first character
$ printf '%s\n' "${v^}"
Hello
# All characters
$ printf '%s\n' "${v^^}"
HELLO
# Alternative
$ v="hello world"
$ declare -u string="$v"
$ echo "$string"
HELLO WORLD

소문자로

$ v="BYE"
# Just the first character
$ printf '%s\n' "${v,}"
bYE
# All characters
$ printf '%s\n' "${v,,}"
bye
# Alternative
$ v="HELLO WORLD"
$ declare -l string="$v"
$ echo "$string"
hello world

토글 케이스

$ v="Hello World"
# All chars
$ echo "${v~~}"
hELLO wORLD
$ echo "${v~}"
# Just the first char
hello World

매개 변수 간접 참조

Bash 간접 지정은 다른 변수에 이름이 들어있는 변수의 값을 가져올 수 있습니다. 변수 예 :

$ red="the color red"
$ green="the color green"

$ color=red
$ echo "${!color}"
the color red
$ color=green
$ echo "${!color}"
the color green

간접 확장 사용법을 보여주는 몇 가지 예 :

 $ foo=10
 $ x=foo
 $ echo ${x}      #Classic variable print  
 foo  
 
 $ foo=10
 $ x=foo
 $ echo ${!x}     #Indirect expansion
 10

한 가지 더 예 :

$ argtester () { for (( i=1; i<="$#"; i++ )); do echo "${i}";done; }; argtester -ab -cd -ef 
1   #i expanded to 1 
2   #i expanded to 2
3   #i expanded to 3

$ argtester () { for (( i=1; i<="$#"; i++ )); do echo "${!i}";done; }; argtester -ab -cd -ef 
-ab     # i=1 --> expanded to $1 ---> expanded to first argument sent to function
-cd     # i=2 --> expanded to $2 ---> expanded to second argument sent to function
-ef     # i=3 --> expanded to $3 ---> expanded to third argument sent to function

기본값 대체

${parameter:-word}

매개 변수가 설정되지 않았거나 널 (null)이면 단어 확장이 대체됩니다. 그렇지 않으면 매개 변수의 값이 대체됩니다.

$ unset var
$ echo "${var:-XX}"     # Parameter is unset -> expansion XX occurs
XX
$ var=""                # Parameter is null -> expansion XX occurs
$ echo "${var:-XX}"
XX
$ var=23                # Parameter is not null -> original expansion occurs
$ echo "${var:-XX}"
23
${parameter:=word}

매개 변수가 설정되지 않았거나 널인 경우 단어 확장이 매개 변수에 지정됩니다. 그런 다음 매개 변수의 값이 대체됩니다. 이런 식으로 위치 매개 변수와 특수 매개 변수를 할당 할 수 없습니다.

$ unset var
$ echo "${var:=XX}"     # Parameter is unset -> word is assigned to XX
XX
$ echo "$var"
XX
$ var=""                # Parameter is null -> word is assigned to XX
$ echo "${var:=XX}"
XX
$ echo "$var"
XX
$ var=23                # Parameter is not null -> no assignment occurs
$ echo "${var:=XX}"
23
$ echo "$var"
23

변수가 비어 있거나 설정되지 않은 경우 오류

이것에 대한 의미는 기본값 대체와 유사하지만 기본값 대신에 제공된 오류 메시지와 함께 오류가 발생합니다. 양식은 ${VARNAME?ERRMSG}${VARNAME:?ERRMSG} 입니다. 변수가 설정되지 않았거나 비어있는 경우에는 : 가있는 양식은 오류가 발생하지만 변수가 설정되지 않은 경우 양식을 사용하지 않으면 오류가 발생합니다. 오류가 발생하면 ERRMSG 가 출력되고 종료 코드는 1 로 설정됩니다.

#!/bin/bash
FOO=
# ./script.sh: line 4: FOO: EMPTY
echo "FOO is ${FOO:?EMPTY}"
# FOO is 
echo "FOO is ${FOO?UNSET}"
# ./script.sh: line 8: BAR: EMPTY
echo "BAR is ${BAR:?EMPTY}"
# ./script.sh: line 10: BAR: UNSET
echo "BAR is ${BAR?UNSET}"

계속 진행하려면 각각의 오류 발생 echo 문 위의 전체 예제를 주석 처리해야합니다.

문자열의 시작 부분에서 패턴 삭제

최단 시합 :

$ a='I am a string'
$ echo "${a#*a}"
m a string

최장 경기 :

$ echo "${a##*a}"
 string

문자열 끝에서 패턴 삭제

최단 시합 :

$ a='I am a string'
$ echo "${a%a*}"
I am 

최장 경기 :

$ echo "${a%%a*}"
I 

문자열의 패턴 바꾸기

첫 경기 :

$ a='I am a string'
$ echo "${a/a/A}"
I Am a string

모든 경기 :

$ echo "${a//a/A}"
I Am A string

경기 시작 :

$ echo "${a/#I/y}"
y am a string

마지막 경기 :

$ echo "${a/%g/N}"
I am a strinN

패턴을 아무것도 대체하지 마십시오.

$ echo "${a/g/}"
I am a strin

배열 항목에 접두어 추가 :

$ A=(hello world)
$ echo "${A[@]/#/R}"
Rhello Rworld

확장하는 동안 munging

변수는 반드시 값으로 확장 할 필요는 없습니다. 확장 중에 하위 문자열을 추출 할 수 있습니다. 이는 파일 확장자 또는 경로 부분을 추출하는 데 유용 할 수 있습니다. 공백 문자는 일반적인 의미를 지닙니다 .* 는 임의의 문자 시퀀스가 ​​뒤 따르는 리터럴 점을 나타냅니다. 그것은 정규 표현식이 아닙니다.

$ v=foo-bar-baz
$ echo ${v%%-*}
foo
$ echo ${v%-*}
foo-bar
$ echo ${v##*-}
baz
$ echo ${v#*-}
bar-baz

이 기본값을 사용하여 변수를 확장 할 수도 있습니다 - 나는 사용자의 편집기를 호출하고 싶은 말은, 그러나 하나를 설정하지 적이 있다면 나는 그들에게주고 싶은 vim .

$ EDITOR=nano
$ ${EDITOR:-vim} /tmp/some_file
# opens nano
$ unset EDITOR
$ $ ${EDITOR:-vim} /tmp/some_file
# opens vim

이 확장을 수행하는 두 가지 다른 방법이 있는데, 관련 변수가 비어 있거나 설정되지 않았는지에 따라 다릅니다. 사용 :- 변수가 설정하거나 동안 비어 중 하나 인 경우 기본값을 사용합니다 - 변수가 설정되지 않은 경우에만 기본값을 사용하지만이 빈 문자열로 설정되어있는 경우 변수를 사용합니다 :

$ a="set"
$ b=""
$ unset c
$ echo ${a:-default_a} ${b:-default_b} ${c:-default_c}
set default_b default_c
$ echo ${a-default_a} ${b-default_b} ${c-default_c}
set default_c

기본값과 마찬가지로 대안을 줄 수 있습니다. 특정 변수를 사용할 수없는 경우 기본값이 사용되는 경우 변수를 사용할 수있는 경우 대체 변수가 사용됩니다.

$ a="set"
$ b=""
$ echo ${a:+alternative_a} ${b:+alternative_b}
alternative_a

이러한 확장을 중첩 할 수 있다는 점을 고려할 때 명령 줄 플래그에 인수를 제공 할 때 대안을 사용하면 특히 유용합니다.

$ output_file=/tmp/foo
$ wget ${output_file:+"-o ${output_file}"} www.stackexchange.com
# expands to wget -o /tmp/foo www.stackexchange.com
$ unset output_file
$ wget ${output_file:+"-o ${output_file}"} www.stackexchange.com
# expands to wget  www.stackexchange.com 

매개 변수 확장 및 파일 이름

Bash 매개 변수 확장을 사용하여 basenamedirname 과 같은 일반적인 파일 이름 처리 작업을 에뮬레이션 할 수 있습니다.

이를 예제 경로로 사용합니다.

FILENAME="/tmp/example/myfile.txt"

dirname 을 에뮬레이트하고 파일 경로의 디렉토리 이름을 리턴하려면 다음을 수행하십시오.

echo "${FILENAME%/*}"
#Out: /tmp/example

basename $FILENAME 을 에뮬레이트하고 파일 경로의 파일 이름을 반환하려면 다음을 수행하십시오.

echo "${FILENAME##*/}"
#Out: myfile.txt

basename $FILENAME .txt 를 에뮬레이션하고 .txt. 없이 파일 이름을 반환합니다 .txt. 신장:

BASENAME="${FILENAME##*/}"
echo "${BASENAME%%.txt}"
#Out: myfile


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow