我有这段代码,它打印了正确的结果,但我不知道如何将最后一行的回显获取到变量中。
# 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[*]}" )
但我得到的结果是“科技新闻博客”,数组之间有空格而不是“-”。
答案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
(...)
引入一个子shell。所以$URL
在那之后不会被设置(仍然具有子 shell 之前的值)。你要:
IFS=-
read -r -a host_name_array <<< "$(hostname)"
unset 'host_name_array[${#host_name_array[@]}-1]'
URL="${host_name_array[*]}"
"${host_name_array[*]}"
$IFS
就像"$*"
在 standard 中一样,将数组中的元素连接到第一个字符上sh
。
如果您使用子 shell 的原因是因为您不想$IFS
全局修改,则可以在给出$IFS
本地作用域的函数中执行此操作:
f() {
local IFS=-
...
}
f
或者使用命令替换来创建子 shell,但允许将数据传递到父 shell:
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
输出用空格分隔的单词。
答案4
巴什具体答案:鞭子叉子!
由于这已经使用了 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"