我知道我可以从变量前面删除子字符串:
X=foobarbaz
echo ${X#foo} # barbaz
...以及从变量的后面:
echo ${X%baz} # foobar
我如何将两者结合起来?我试过了:
echo ${{X#foo}%baz} # "bad substitution"
echo ${${X#foo}%baz} # "bad substitution"
echo ${X#foo%baz} # foobarbaz
我不思考我可以使用中间变量,因为它在 中使用find -exec
,如下所示:
find ./Source -name '*.src' \
-exec bash -c 'myconvert -i "{}" -o "./Dest/${0#./Source/%.src}.dst"' {} \;
答案1
我认为这是不可能的(但很想被证明是错误的)。但是,您可以使用中间变量。与其他实例一样,运行bash -c
者-exec
只是一个 bash 实例:
$ find . -type f
./foobarbaz
$ find . -type f -exec bash -c 'v=${0#./foo}; echo ${v%baz}' {} \;
bar
所以我看不出为什么这行不通(如果我理解你想要正确做的事情):
find ./Source -name '*.src' \
-exec bash -c 'v=${0%.src}; \
myconvert -i "{}" -o "./Dest/${v#./Source/}.dst"' {} \;
答案2
通常的方法是分两步进行:
x=foobarbaz
y=${x#foo} # barbaz
z=${y%baz} # bar
由于这是“参数扩展”,因此需要“参数”(变量)才能执行任何替换。这意味着需要 y 和 z。即使它们可能是相同的变量:
x=foobarbaz
x=${x#foo} # barbaz
x=${x%baz} # bar
find ./Source/ -name '*.src' -exec \
bash -c '
x=${1#./Source/}
myconvert -i "$1" -o "./Dest/${x%.src}.dst"
' shname {} \;
其中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
一旦您确信它符合您的要求,请注释掉回声。
答案3
我总是一步一步地做:
X=foobarbaz; X="${X#foo}"; X="${X%baz}"