문자열의 마지막 문자를 삭제하고 싶습니다.이 작은 스크립트를 시도했습니다.
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
하지만 "lkj"를 인쇄합니다. 제가 뭘 잘못하고 있습니까?
문자열의 마지막 문자를 삭제하고 싶습니다.이 작은 스크립트를 시도했습니다.
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
하지만 "lkj"를 인쇄합니다. 제가 뭘 잘못하고 있습니까?
답변:
POSIX 셸에서 구문 ${t:-2}
은 다른 것을 의미합니다. t
if t
는 set 의 값으로 설정되고 null이 아닌 값으로 확장 되고 그렇지 않으면 value로 확장됩니다 2
. 매개 변수 확장으로 단일 문자를 자르려면 원하는 구문은 다음과 같습니다.${t%?}
그의 주 ksh93
, bash
또는 zsh
, ${t:(-2)}
또는 ${t: -2}
(공간주의) 이다 문자열 확장 법적 그러나 그들은 (끝에서의 위치에이 개 문자를 시작하는 문자열을 반환하기 때문에 당신이 원하는 것을 아마하지 않습니다 즉, 그것은 제거 첫 번째 문자 i
의를 문자열 ijk
).
자세한 내용은 Bash Reference Manual의 Shell Parameter Expansion 섹션을 참조하십시오.
${parameter%word}
는 가장 짧은 접미사 패턴 일치를 제거합니다.word
man bash
로 bash
위의 4.2, 당신은 할 수 있습니다 :
${var::-1}
예:
$ a=123
$ echo "${a::-1}"
12
이전 버전 bash
(예 : bash 3.2.5
OS X)의 경우 콜론 사이와 뒤에 콜론을 두어야합니다.
${var: : -1}
bash
버전 4.2-alpha 이상에서 작동하며 , 내가 액세스 할 수있는 버전이 너무 나쁩니다. :-/
${var:offset:lenght}
에 추가되었습니다 bash 4.2
. OSX가에 대한 자체 패치를 추가했을 수도 있습니다 bash
.
OR을 n
사용하지 않는 행에서 마지막 문자 를 제거합니다 .sed
awk
> echo lkj | rev | cut -c (n+1)- | rev
예를 들어 다음을 사용하여 마지막 문자 one character
를 삭제할 수 있습니다 .
> echo lkj | rev | cut -c 2- | rev
> lk
에서 rev
맨 :
설명
rev 유틸리티는 지정된 파일을 모든 행의 문자 순서를 반대로하여 표준 출력으로 복사합니다. 파일을 지정하지 않으면 표준 입력을 읽습니다.
최신 정보:
문자열의 길이를 모르는 경우 다음을 시도하십시오.
$ x="lkj"
$ echo "${x%?}"
lk
sed를 사용하면
sed 's/.$//'
그러면 단일 에코 가 echo ljk | sed 's/.$//'
입니다.
이것을 사용하여 1 줄 문자열은 모든 크기가 될 수 있습니다.
쉘에 따라 몇 가지 옵션 :
t=${t%?}
t=`expr " $t" : ' \(.*\).'`
t=${t[1,-2]}
t=${t:0:-1}
t=${t:0:${#t}-1}
t=${t/%?}
t=${t/~(E).$/}
@ {t=$1} ~~ $t *?
모든 것이 마지막 문자 를 제거해야 하지만 일부 구현 (멀티 바이트 문자를 지원하지 않는 구현)은 마지막 바이트를 대신 제거합니다 (멀티 바이트 인 경우 마지막 문자가 손상 될 수 있음) ).
expr
변형을 가정 $t
한 개 이상의 개행 문자로 끝나지 않습니다. 결과 문자열이 될 수있을 테니까요 경우에도 0이 아닌 종료 상태를 반환합니다 0
(또는 000
심지어 -0
일부 구현과 함께). 문자열에 유효하지 않은 문자가 포함되어 있으면 예기치 않은 결과가 발생할 수도 있습니다.
t=${t%?}
는 Bourne이 아니지만 요즘 Bourne 쉘을 발견하지 못할 것입니다. ${t%?}
그래도 다른 모든 것들에서 작동합니다.
fish
진행중인 작업입니다. string
Q & A 당시에 는 내장 을 도입 한 2.3.0이 릴리스되지 않았습니다. 내가 테스트하고있는 버전으로, 당신은 string replace -r '(?s).\z' '' -- $t
(그리고 그들이 그것을 바꾸고 싶을 것이라고 기대할 것입니다, 그들은 PCRE에 전달하는 플래그를 변경해야합니다) 또는 더 복잡한 것들. 또한 줄 바꿈 문자를 제대로 처리하지 못하기 때문에 줄 바꿈 문자도 변경하려고한다는 것을 알고 있습니다.
가장 휴대 가능하고 가장 짧은 대답은 거의 확실합니다.
${t%?}
이것은 bash, sh, ash, dash, busybox / ash, zsh, ksh 등에서 작동합니다.
구식 쉘 매개 변수 확장을 사용하여 작동합니다. 특히, glob 패턴과 %
일치하는 가장 작은 일치하는 매개 변수 접미사를 제거 하도록 지정합니다 (예 : 모든 문자).t
?
"작은 접미사 패턴 제거"를 참조하십시오 여기에 A (훨씬)에 대한 자세한 설명과 많은 배경. 또한 man bash
"매개 변수 확장"에서 쉘에 대한 문서 (예 :)를 참조하십시오 .
당신은 제거하기를 원한다면 사이드 참고로, 첫 번째 대신 문자를, 다음을 사용 ${t#?}
하기 때문에, #
대신 다시 (접미사)의 문자열 (접두사)의 전면에서 일치.
또한 주목할 가치가있는 것은 %
및 #
가지고 %%
있고있는 ##
버전 이며, 가장 짧은 버전이 아닌 주어진 패턴 의 가장 긴 버전 과 일치합니다 . 모두 ${t%%?}
와 ${t##?}
이 경우 자신의 하나의 연산자로 동일한 기능을 수행 할 것입니다,하지만 (그래서 쓸모없는 여분의 문자를 추가하지 마십시오). 주어진 ?
패턴이 단일 문자와 만 일치 하기 때문 입니다. A의 믹스 *
일부 비 와일드 카드로 물건은 더 흥미있어 %%
하고 ##
.
매개 변수 확장을 이해하거나 최소한 그것들의 존재와 그것을 찾는 방법을 아는 것은 많은 맛의 쉘 스크립트를 작성하고 해독하는데 매우 유용합니다. 음 ... 그들은 ... 때문에 매개 변수 확장은 종종 많은 사람들에게 비밀 쉘 부두 모양 이다 (당신이 "매개 변수 확장"을 찾기 위해 알고있는 경우에 아주 잘 설명하지만) 비밀 쉘 부두를. 쉘에 갇혀있을 때 공구 벨트에 확실히 좋습니다.
순수한 bash의 가능한 사용법을 완료하려면 다음을 수행하십시오.
#!/bin/bash
# Testing substring removal
STR="Exemple string with trailing whitespace "
echo "'$STR'"
echo "Removed trailing whitespace: '${STR:0:${#STR}-1}'"
echo "Removed trailing whitespace: '${STR/%\ /}'"
첫 번째 구문은 문자열에서 하위 문자열을 가져 오고 구문은
다음과 같습니다. 두 번째 구문의 경우 '줄 끝에서'를 의미 하는 부호를 확인하고 구문은
${STRING:OFFSET:LENGTH}
%
${STRING/PATTERN/SUBSTITUTION}
그리고 여기 위에서 언급 한 두 가지 짧은 형태가 있습니다.
echo "Removed trailing whitespace: '${STR::-1}'"
echo "Removed trailing whitespace: '${STR%\ }'"
여기서 가장 짧은 일치 패턴 (여기서 이스케이프 된 공간 '\' 으로 표시되는 PARAMETER 의 끝 -여기서 STR로%
표시됨)을 의미 하는 부호를 다시 알 수 있습니다.