내 dash
스크립트는 다음과 같은 형식의 매개 변수를 사용합니다 hostname:port
.
myhost:1234
포트는 선택적인 반면,
myhost
호스트와 포트를 별도의 변수로 읽어야합니다. 첫 번째 경우에는 다음을 수행 할 수 있습니다.
HOST=${1%%:*}
PORT=${1##*:}
그러나 포트가 생략 된 두 번째 경우에는 작동하지 않습니다. echo ${1##*:}
빈 문자열 대신 호스트 이름을 반환합니다.
Bash에서 나는 할 수 있었다 :
IFS=: read A B <<< asdf:111
그러나 그것은 작동하지 않습니다 dash
.
나는에 문자열을 분할 할 수 있습니다 :
외부 프로그램을 (호출하지 않고, 대시 awk
, tr
등)?
답변
그냥 해:
case $1 in
(*:*) host=${1%:*} port=${1##*:};;
(*) host=$1 port=$default_port;;
esac
유사한 값 ( 포트 부분이 없는 IPv6 주소) 을 설명 case $1
하도록 case ${1##*[]]}
to 를 변경할 수 있습니다 .$1
[::1]
분할하려면 split + glob 연산자를 사용하십시오 (매개 변수를 인용 부호로 묶지 말고 그대로 사용하십시오 ).
set -o noglob # disable glob part
IFS=: # split on colon
set -- $1 # split+glob
host=$1 port=${2:-$default_port}
(그러나 위의 IPv6 주소와 같이 콜론을 포함하는 호스트 이름은 허용되지 않습니다).
그 split + glob 연산자는 방해가되어 나머지 시간에 많은 해를 끼치므로 필요할 때마다 사용하는 것이 공정한 것처럼 보일 것입니다 (그러나 POSIX sh
에는 없음을 고려할 때 특히 사용하는 것이 번거 롭습니다 변수 (위한도, 로컬 영역에 대한 지원을 $IFS
여기)이나 옵션 (위한 noglob
여기) (비록 ash
유도체 좋아 dash
함께 AT & T의 구현과 (DO 그들 중 일부 ksh
, zsh
및 bash
상기 4.4))는.
참고 IFS=: read A B <<< "$1"
자신의 몇 가지 문제가 있습니다 :
-r
백 슬래시가 특수 처리를 수행한다는 것을 잊어 버렸습니다 .- 그것은 분할 것이다
[::1]:443
로[
하고:1]:443
대신[
(과 빈 문자열에 대해 사용자가 필요할 것IFS=: read -r A B rest_ignored
또는[::1]
과443
) (하는 당신이 방법을 사용할 수 없습니다 - 그것은 개행 문자의 첫 번째 발생을지나 모든 것을 제거하므로 임의의 문자열과 함께 사용할 수 없습니다 ( 또는
-d ''
in 을 사용 하고 데이터에 NUL 문자가 포함되어 있지 않는 한 herestrings 또는 heredocs는 추가 줄 바꿈 문자!)zsh
bash
- in
zsh
(구문이 나오는 곳) 및bash
, 여기서 문자열은 임시 파일을 사용하여 구현되므로 일반적으로${x#y}
split 또는 glob 연산자를 사용하는 것보다 덜 효율적 입니다.
답변
:
별도의 문장에서 제거하십시오 . 또한 입력에서 $ host를 제거하여 포트를 가져옵니다.
host=${1%:*}
port=${1#"$host"}
port=${port#:}
답변
또 다른 생각 :
host=${1%:*}
port=${1##*:}
[ "$port" = "$1" ] && port=''
답변
here 문자열은 단일 행 here 문서의 구문 바로 가기입니다.
$ set myhost:1234
$ IFS=: read A B <<EOF
> $1
> EOF
$ echo "$A"
myhost
$ echo "B"
1234