Remove substring da frente e verso da variável

6

Eu sei que posso remover subseqüências da frente de uma variável:

X=foobarbaz
echo ${X#foo}       # barbaz

... e na parte de trás de uma variável:

echo ${X%baz}       # foobar

Como eu combino os dois? Eu tentei:

echo ${{X#foo}%baz}    # "bad substitution"
echo ${${X#foo}%baz}   # "bad substitution"
echo ${X#foo%baz}      # foobarbaz

Eu não acho que eu posso usar uma variável intermediária, porque isso está sendo usado em find -exec , algo como o seguinte:

find ./Source -name '*.src' \
    -exec bash -c 'myconvert -i "{}" -o "./Dest/${0#./Source/%.src}.dst"' {} \;
    
por Roger Lipscombe 02.04.2016 / 21:50

3 respostas

7

Eu não acho que isso seja possível (mas adoraria estar errado). No entanto, você pode usar uma variável intermediária. O bash -c executado por -exec é apenas uma instância do bash, como qualquer outra:

$ find . -type f
./foobarbaz
$ find . -type f -exec bash -c 'v=${0#./foo}; echo ${v%baz}'  {} \;
bar

Portanto, não vejo razão para que isso não funcione (se entendi o que você está tentando fazer corretamente):

find ./Source -name '*.src' \
     -exec bash -c 'v=${0%.src}; \ 
        myconvert -i "{}" -o "./Dest/${v#./Source/}.dst"' {} \;
    
por 02.04.2016 / 22:10
3

A maneira usual é fazer isso em duas etapas:

x=foobarbaz
y=${x#foo}       # barbaz
z=${y%baz}       # bar

Como isso é "Expansões de Parâmetros", um "Parâmetro" (variável) é necessário para poder realizar qualquer substituição. Isso significa que yez são necessários. Mesmo se eles pudessem ser a mesma variável:

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 {} \;

Onde shname é o parâmetro $0 e o próximo {} é o parâmetro $1 para a chamada de bash.

Uma alternativa mais simples é fazer um cd ./Source no início para evitar remover essa parte mais tarde. Algo como:

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

Quando estiver convencido de que faz o que quiser, comente o eco.

    
por 02.04.2016 / 22:25
1

Eu sempre faço um passo de cada vez:

X=foobarbaz; X="${X#foo}"; X="${X%baz}"
    
por 02.04.2016 / 21:53

Tags