Bash에서 문자열의 마지막 x 문자에 액세스


125

${string:0:3}하나를 사용하면 문자열의 처음 3 자에 액세스 할 수 있다는 것을 알았습니다 . 마지막 세 문자에 액세스하는 똑같이 쉬운 방법이 있습니까?

답변:


236

의 마지막 세 문자 string:

${string: -3}

또는

${string:(-3)}

( 첫 번째 형식에서 :와 사이의 공간을 생각하십시오 -3).

참조 설명서에서 쉘 매개 변수 확장을 참조하십시오 .

${parameter:offset}
${parameter:offset:length}

Expands to up to length characters of parameter starting at the character
specified by offset. If length is omitted, expands to the substring of parameter
starting at the character specified by offset. length and offset are arithmetic
expressions (see Shell Arithmetic). This is referred to as Substring Expansion.

If offset evaluates to a number less than zero, the value is used as an offset
from the end of the value of parameter. If length evaluates to a number less than
zero, and parameter is not ‘@’ and not an indexed or associative array, it is
interpreted as an offset from the end of the value of parameter rather than a
number of characters, and the expansion is the characters between the two
offsets. If parameter is ‘@’, the result is length positional parameters
beginning at offset. If parameter is an indexed array name subscripted by ‘@’ or
‘*’, the result is the length members of the array beginning with
${parameter[offset]}. A negative offset is taken relative to one greater than the
maximum index of the specified array. Substring expansion applied to an
associative array produces undefined results.

Note that a negative offset must be separated from the colon by at least one
space to avoid being confused with the ‘:-’ expansion. Substring indexing is
zero-based unless the positional parameters are used, in which case the indexing
starts at 1 by default. If offset is 0, and the positional parameters are used,
$@ is prefixed to the list.

이 답변은 몇 가지 일반적인 견해를 얻으므로 John Rix 의 의견 을 해결할 가능성을 추가하겠습니다 . 그가 언급했듯이 문자열 길이가 3 미만이면 ${string: -3}빈 문자열로 확장됩니다. 이 경우을 확장 string하려면 다음을 사용할 수 있습니다.

${string:${#string}<3?0:-3}

이것은 쉘 산술?: 에서 사용될 수있는 삼항 if 연산자를 사용합니다 . 설명 된대로 오프셋은 산술 표현식이므로 유효합니다.


5
문자열이 제공 한 음수 오프셋보다 짧으면 작동하지 않습니다. 이러한 경우에는 빈 문자열이 표시됩니다.
John Rix 2014 년

2
@gniourf_gniourf 명령 대체와 함께 이것을 어떻게 사용할 수 있습니까? 내 호스트 이름의 마지막 세 문자를 추출하려고합니다 deppfx@localhost:/tmp$ echo ${$(hostname): -3} -bash: ${$(hostname): -3}: bad substitution
deppfx

3
@deppfx : Bash에서는 할 수 없습니다. 임시 변수 사용 : temp=$(hostname); echo "${temp: -3}". Bash에는 HOSTNAME변수가 있습니다 (의 출력과 다를 수도 있고 다를 수도 없음 hostname). 사용하려면 echo "${HOSTNAME: -3}".
gniourf_gniourf

파이프의 출력에서 ​​이것을 어떻게 사용할 수 있습니까? 예를 들어, some func | echo ${string: -3}- 어떻게의 출력에 할당 할 some func로를 string?
Michael Hays

1
@MichaelHays : 함수의 출력을 할당 string=$(some func)한 다음 echo "${string: -3}".
gniourf_gniourf

48

다음을 사용할 수 있습니다 tail.

$ foo="1234567890"
$ echo -n $foo | tail -c 3
890

마지막 세 문자를 얻는 방법은 다음과 같습니다.

echo $foo | rev | cut -c1-3 | rev

2
"꼬리"는 bash를 사용할 수 없을 때 대시에서도 유용합니다. 예 : upstart 스크립트 섹션.
vskubriev

13

또 다른 해결 방법은 grep -o약간의 정규식 마법 을 사용 하여 3 개의 문자와 줄 끝을 얻는 것입니다.

$ foo=1234567890
$ echo $foo | grep -o ...$
890

3 자 미만의 문자열의 경우 선택적으로 1 ~ 3 개의 마지막 문자를 가져 오려면 egrep다음 정규식과 함께 사용할 수 있습니다 .

$ echo a | egrep -o '.{1,3}$'
a
$ echo ab | egrep -o '.{1,3}$'
ab
$ echo abc | egrep -o '.{1,3}$'
abc
$ echo abcd | egrep -o '.{1,3}$'
bcd

5,10마지막 5 ~ 10 개의 문자를 가져 오는 것과 같이 다른 범위를 사용할 수도 있습니다 .


7

gniourf_gniourf의 질문과 대답을 일반화하기 위해 (이것이 내가 검색 한 것과 같이) , 예를 들어 끝에서 7 번째부터 끝에서 3 번째까지의 문자 범위 를 자르려면 다음 구문을 사용할 수 있습니다.

${string: -7:4}

여기서 4는 코스 길이 (7-3)입니다.

또한 gniourf_gniourf의 솔루션이 분명히 최고이고 가장 깔끔하지만 cut 을 사용하여 대체 솔루션을 추가하고 싶었습니다 .

echo $string | cut -c $((${#string}-2))-$((${#string}))

$ {# string} 길이를 별도의 변수로 정의하여 두 줄로 수행하면 더 읽기 쉽습니다.


다른 답변에서 언급되지 않은 변형 cut은 시작 / 중지를 먼저 계산 한 다음 매개 변수 확장에서 이러한 변수를 사용하는 이러한 접근 방식 을 결합 하는 것입니다 (또한 cutbash 오프셋은 각각 1과 0에서 시작 하므로 언급 할 가치 가 있습니다. 계산으로 계산할 수 있습니다. 여기서는하지 않습니다.) start=$((${#string}-3)); stop=$((${#string}));그리고 echo ${string: $start : $stop}vsecho $string | cut -c "$start"-"$stop"
michael

(오, 신경 쓰지 마세요-내 주석이 문자열이 너무 짧아서 출력이 전혀 발생하지 않는 문제를 해결하지 못함을 알 수 있습니다 (절단 및 문자열 매개 변수 확장 모두). 그래도 변수로 분할 ( 반드시 읽기 쉽게 & 여전히 좋은 아이디어라고한다) 여분의 명령에 밖으로 호출하지 않고, 나는 생각한다).
마이클
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.