이 코드가 있고 올바른 결과가 인쇄되지만 마지막 줄의 에코를 변수로 가져오는 방법을 모르겠습니다.
# hostname is 'tech-news-blog-324344' . Setting it into array host_name_array
IFS='-' read -r -a host_name_array <<< "$(hostname)"
#removing the last part of string after last "-"
unset 'host_name_array[${#host_name_array[@]}-1]'
( IFS=$'-'; echo "${host_name_array[*]}" )
#result is 'tech-news-blog'
마지막 행의 값을 변수에 어떻게 넣을 수 있나요? 나는 다음을 시도했습니다 :
( IFS=$'-'; URL="${host_name_array[*]}" )
그러나 내가 얻은 결과는 "-" 대신 어레이 사이에 공백이 있는 "Technology News Blog"입니다.
답변1
런타임 시 IFS='-' read -r -a host_name_array <<< "$(hostname)"
배열은 (tech news blog 324344)
.
마지막 요소를 삭제한 후 unset 'host_name_array[${#host_name_array[@]}-1]'
배열은 입니다 (tech news blog)
.
따라서 echo 를 얻으려면 다음 tech-news-blog
과 같이 일부 대체가 이루어져야 합니다 .echo "${host_name_array[*]}"
tech news blog
tr과 함께:echo "${host_name_array[*]}" | tr ' ' '-'
sed:echo "${host_name_array[*]}" | sed 's/ /-/g'
답변2
다음과 같이 구분된 요소를 출력한 다음 -
매개변수 확장을 통해 마지막 요소를 제거하여 이를 수행할 수 있습니다.-
$ var=$(printf '%s-' "${host_name_array[@]}")
$ echo "$var"
foo-bar-spam-egg-
$ var="${var%-}"
$ echo "$var"
foo-bar-spam-egg
또한 요소가 첫 번째 문자로 구분되어 전체적으로 출력되는 것을 ${host_name_array[@]}
방지 해야 합니다 .${host_name_array[*]}
IFS
간단한 매개변수 확장을 통해 원하는 결과를 얻을 수 있습니다.
${var%-*}
예:
$ var=$(hostname)
$ echo "${var%-*}"
답변3
(...)
서브쉘을 소개합니다. 따라서 $URL
그 이후에는 설정되지 않습니다(여전히 하위 쉘의 이전 값이 유지됩니다). 당신이 원하는 것:
IFS=-
read -r -a host_name_array <<< "$(hostname)"
unset 'host_name_array[${#host_name_array[@]}-1]'
URL="${host_name_array[*]}"
"${host_name_array[*]}"
$IFS
표준과 마찬가지로 "$*"
배열의 요소를 첫 번째 문자에 연결합니다 sh
.
$IFS
서브쉘을 사용하는 이유가 전역적으로 수정하고 싶지 않기 때문이라면 $IFS
로컬 범위가 지정된 함수에서 이를 수행할 수 있습니다.
f() {
local IFS=-
...
}
f
또는 명령 대체를 사용하여 하위 쉘을 생성하지만 데이터가 상위 쉘로 전달되도록 허용합니다.
URL=$(IFS=-; printf '%s\n' "${host_name_array[*]}")
그러나 여기서는 표준 sh
확장을 사용하여 후행 구성 요소를 제거하겠습니다.
URL=$(uname -n) # uname -n is the standard equivalent of hostname
URL=${URL%-*}
위와 비교하면 다음과 같은 장점이 있습니다.
- 텍스트에 개행 문자가 포함된 경우에도 작동합니다(여기서는 호스트 이름에서는 그럴 가능성이 낮지만).
- 텍스트가 포함되지 않으면
-
아무것도 삭제되지 않습니다. - 더 효율적입니다.
read <<< $(hostname)
run 을 의미하고hostname
, 파이프를 통해 출력을 읽고, 임시 파일에 저장하고,read
해당 파일의 첫 번째 줄을 읽습니다. - 이러한 임시 변수를 사용하여 변수 네임스페이스를 파괴하지 않습니다.
- 더 짧습니다.
- 휴대용입니다.
bash
코드를 실행하기 위해 설치가 필요하지 않습니다 . 시스템sh
이면 충분합니다.
어떤 경우 에라도,변수를 인용하는 것을 잊지 마세요목록 컨텍스트에서 사용하는 경우:
printf '%s\n' "$URL"
할 때:
$URL 에코
분할+글로브 연산자를 호출하고 있습니다. 따라서 $IFS
여전히 포함되어 -
있으면 $URL
분할되어 -
공백 echo
으로 구분된 단어가 출력됩니다.
답변4
세게 때리다구체적인 답변 : 채찍포크!
이것은 이미 bashism을 사용하고 있거나 sed
다른 tr
외부 도구는 쓸모가 없기 때문에:
IFS='-' read -r -a host_name_array < <(hostname)
#removing the last part of string after last "-"
unset host_name_array[${#host_name_array[@]}-1]
shorted=${host_name_array[*]}
echo ${shorted// /-}
아니면 더 간단합니다:
이는 더 짧고 빠르며 간단합니다.
read myvar < <(hostname)
echo ${myvar%-*}
host_name_array
다른 이유로 필요한 경우 :
read shorted < <(hostname)
host_name_array=(${shorted//-/ })
shorted=${shorted%-*}
그래서 당신은 배열을 가지고 있습니다그리고짧은 호스트 이름:
declare -p host_name_array shorted
다음과 유사한 내용이 반환됩니다.
declare -a host_name_array='([0]="tech" [1]="news" [2]="blog" [3]="324344")'
declare -- shorted="tech-news-blog"