我有的是这个:
progname=${0%.*}
progname=${progname##*/}
Run Code Online (Sandbox Code Playgroud)
这可以嵌套(或不嵌套)成一行,即单个表达式吗?
我正在尝试从脚本名称中删除路径和扩展名,以便只保留基本名称.以上两行都运行正常.我的"C"性质只是让我更加混淆这些.
Tim*_*Tim 46
如果是通过嵌套,你的意思是这样的:
#!/bin/bash
export HELLO="HELLO"
export HELLOWORLD="Hello, world!"
echo ${${HELLO}WORLD}Run Code Online (Sandbox Code Playgroud)
然后不,你不能嵌套${var}表达式.bash语法扩展器不会理解它.
但是,如果我理解你的问题,你可能会看一下使用basename命令 - 它从给定的文件名中删除路径,如果给定扩展名,也会删除它.例如,运行basename /some/path/to/script.sh .sh将返回script.
小智 42
Bash支持间接扩展:
$ FOO_BAR="foobar"
$ foo=FOO
$ foobar=${foo}_BAR
$ echo ${foobar}
FOO_BAR
$ echo ${!foobar}
foobar
Run Code Online (Sandbox Code Playgroud)
这应该支持您正在寻找的嵌套.
小智 14
以下选项对我有用:
NAME="par1-par2-par3"
echo $(TMP=${NAME%-*};echo ${TMP##*-})
Run Code Online (Sandbox Code Playgroud)
输出是:
par2
Run Code Online (Sandbox Code Playgroud)
Dee*_*pak 11
一个旧线程,但也许答案是使用间接:$ {!PARAMETER}
例如,请考虑以下几行:
H="abc"
PARAM="H"
echo ${!PARAM} #gives abc
Run Code Online (Sandbox Code Playgroud)
像${${a}}这样的表达不起作用。要解决它,您可以使用eval:
b=value
a=b
eval aval=\$$a
echo $aval
Run Code Online (Sandbox Code Playgroud)
输出是
value
实际上,可以使用两个步骤在bash中创建嵌套变量.
这是一个基于Tim的帖子的测试脚本,使用user1956358建议的想法.
#!/bin/bash
export HELLO="HELLO"
export HELLOWORLD="Hello, world!"
# This command does not work properly in bash
echo ${${HELLO}WORLD}
# However, a two-step process does work
export TEMP=${HELLO}WORLD
echo ${!TEMP}
Run Code Online (Sandbox Code Playgroud)
输出是:
Hello, world!
Run Code Online (Sandbox Code Playgroud)
通过从命令行运行' info bash '然后搜索' Shell Parameter Expansion ' 来解释许多巧妙的技巧.我今天自己一直在读一些,只是失去了大约20分钟的一天,但我的剧本会变得更好......
更新:经过更多阅读后,我建议您根据初步问题选择此替代方案
progname=${0##*/}
Run Code Online (Sandbox Code Playgroud)
它回来了
bash
Run Code Online (Sandbox Code Playgroud)
由于那里已经有很多答案,我只想提出两种不同的方法来完成这两个任务:嵌套参数扩展 和 变量名操作。(所以你会在那里找到四个不同的答案:)。
;) 也没有换行符:progname=${0%.*} progname=${progname##*/}
Run Code Online (Sandbox Code Playgroud)
basenameprogname=$(basename ${0%.*})
Run Code Online (Sandbox Code Playgroud)
这将完成这项工作。
如果你想构造 varname,你可以
foobar="baz"
varname="foo"
varname+="bar"
echo ${!varname}
baz
Run Code Online (Sandbox Code Playgroud)
foobar="baz"
bar="foo"
declare -n reffoobar=${bar}bar
echo $reffoobar
baz
Run Code Online (Sandbox Code Playgroud)
对于OP的原始问题,有一个1行解决方案,即删除文件扩展名的脚本的基本名称:
progname=$(tmp=${0%.*} ; echo ${tmp##*/})
Run Code Online (Sandbox Code Playgroud)
这是另一个,但是,使用了作弊的基本名称:
progname=$(basename ${0%.*})
Run Code Online (Sandbox Code Playgroud)
其他答案已经偏离了OP的原始问题,而是集中在是否可以仅扩展表达式的结果,但遇到了必须显式匹配变量名称的${!var}限制。var话虽如此,如果您用分号将表达式链接在一起,就没有什么可以阻止您得到一行答案。
ANIMAL=CAT
BABYCAT=KITTEN
tmp=BABY${ANIMAL} ; ANSWER=${!tmp} # ANSWER=KITTEN
Run Code Online (Sandbox Code Playgroud)
如果你想让它看起来像一个单一的语句,你可以将它嵌套在一个子shell中,即
ANSWER=$( tmp=BABY${ANIMAL) ; echo ${!tmp} ) # ANSWER=KITTEN
Run Code Online (Sandbox Code Playgroud)
一个有趣的用法是间接作用于 bash 函数的参数。然后,您可以嵌套 bash 函数调用来实现多级嵌套间接,因为我们可以执行嵌套命令:
这是表达式间接的演示:
ANIMAL=CAT
BABYCAT=KITTEN
tmp=BABY${ANIMAL} ; ANSWER=${!tmp} # ANSWER=KITTEN
Run Code Online (Sandbox Code Playgroud)
以下是通过嵌套命令进行多级间接的演示:
ANSWER=$( tmp=BABY${ANIMAL) ; echo ${!tmp} ) # ANSWER=KITTEN
Run Code Online (Sandbox Code Playgroud)