このコードを使用すると、正しい結果が出力されますが、最後の行から変数にエコーを取得する方法がわかりません。
# 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[*]}" )
しかし、「-」の代わりに配列の各要素の間にスペースが含まれる「tech news blog」という結果が表示されます。
IFS='-' read -r -a Host_name_array <<< "$(hostname)"
が実行されると、配列は(tech news blog 324344)
になります。
最後の要素がunset 'Host_name_array[${#Host_name_array[@]}-1]'
で削除された後、配列は(tech news blog)
になります。
したがって、これをtech-news-blog
にエコーするには、echo "${Host_name_array[*]}"
がtech news blog
を生成するため、いくつかの置換を行う必要があります。
Trの場合:echo "${Host_name_array[*]}" | tr ' ' '-'
sed:echo "${Host_name_array[*]}" | sed 's/ /-/g'
これを行うには、-
で区切られた要素を出力し、最後の-
をパラメーター展開によって取り除きます。
$ var=$(printf '%s-' "${Host_name_array[@]}")
$ echo "$var"
foo-bar-spam-Egg-
$ var="${var%-}"
$ echo "$var"
foo-bar-spam-Egg
また、IFS
の最初の文字で区切られた要素全体を出力しないようにするには、${Host_name_array[@]}
ではなく${Host_name_array[*]}
が必要です。
あなたがやろうとしていることは、単純なパラメーター拡張によって実現できます:
${var%-*}
例:
$ var=$(hostname)
$ echo "${var%-*}"
_(...)
_はサブシェルを導入します。したがって、_$URL
_はその後は設定されません(サブシェルの前の値のままです)。あなたが欲しい:
_IFS=-
read -r -a Host_name_array <<< "$(hostname)"
unset 'Host_name_array[${#Host_name_array[@]}-1]'
URL="${Host_name_array[*]}"
_
_"${Host_name_array[*]}"
_は、標準のsh
の_$IFS
_と同様に、_"$*"
_の最初の文字で配列の要素を結合します。
サブシェルを使用する理由が_$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)
は、hostname
を実行し、その出力をパイプ経由で読み取り、それを一時ファイルに格納し、read
にその最初の行を読み取らせることを意味します。bash
をインストールする必要はありません。システムのsh
で十分です。いずれの場合も、リストコンテキストで使用する場合は 変数を引用符で囲んでください :
_printf '%s\n' "$URL"
_
行うとき:
$ URLをエコー
Split + glob演算子を呼び出しています。したがって、_$IFS
_に_-
_がまだ含まれている場合、その_$URL
_は_-
_で分割され、echo
はスペースで区切られた単語を出力します。
これはすでにbashismsを使用しているため、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"