我知道我可以从变量的前面删除子字符串:
X=foobarbaz
echo ${X#foo} # barbaz
Run Code Online (Sandbox Code Playgroud)
...从变量的后面:
echo ${X%baz} # foobar
Run Code Online (Sandbox Code Playgroud)
我如何将两者结合起来?我试过了:
echo ${{X#foo}%baz} # "bad substitution"
echo ${${X#foo}%baz} # "bad substitution"
echo ${X#foo%baz} # foobarbaz
Run Code Online (Sandbox Code Playgroud)
我不认为我可以使用中间变量,因为它在find -exec
, 中使用,如下所示:
find ./Source -name '*.src' \
-exec bash -c 'myconvert -i "{}" -o "./Dest/${0#./Source/%.src}.dst"' {} \;
Run Code Online (Sandbox Code Playgroud)
我认为这是不可能的(但很想被证明是错误的)。但是,您可以使用中间变量。在bash -c
通过运行-exec
仅仅是一个bash的实例,就像任何其他:
$ find . -type f
./foobarbaz
$ find . -type f -exec bash -c 'v=${0#./foo}; echo ${v%baz}' {} \;
bar
Run Code Online (Sandbox Code Playgroud)
所以我看不出为什么这不起作用(如果我理解你正在尝试正确做的事情):
find ./Source -name '*.src' \
-exec bash -c 'v=${0%.src}; \
myconvert -i "{}" -o "./Dest/${v#./Source/}.dst"' {} \;
Run Code Online (Sandbox Code Playgroud)
小智 7
通常的方法是分两步完成:
x=foobarbaz
y=${x#foo} # barbaz
z=${y%baz} # bar
Run Code Online (Sandbox Code Playgroud)
由于这是“参数扩展”,因此需要“参数”(变量)才能执行任何替换。这意味着需要 y 和 z。即使它们可能是相同的变量:
x=foobarbaz
x=${x#foo} # barbaz
x=${x%baz} # bar
Run Code Online (Sandbox Code Playgroud)
find ./Source/ -name '*.src' -exec \
bash -c '
x=${1#./Source/}
myconvert -i "$1" -o "./Dest/${x%.src}.dst"
' shname {} \;
Run Code Online (Sandbox Code Playgroud)
哪里shname
是参数$0
,下一个{}
是$1
bash 调用的参数。
一个更简单的替代方法是cd ./Source
在开始时执行 a以避免稍后删除该部分。就像是:
cd ./Source ### Maybe test that it exist before cd to it.
shopt -s extglob nullglob ### Make sure that correct options are set.
for f in *.src **/*.src; do
echo \
myconvert -i "$f" -o "./Dest/${f%.src}.dst"
done
Run Code Online (Sandbox Code Playgroud)
一旦您确信它可以满足您的要求,请注释掉回声。