A questão principal aqui é que ${PARAMETER/PATTERN/STRING} expansion PATTERN não aceita uma matriz como PARAMETER e, portanto, ${arr[@]} expande para "% > #" .
O efeito disso pode ser visto se você adicionar alguns arquivos:
# touch "% > #somefile.txt"
# touch "%>#somefile.txt"
Seu comando resultaria em:
#somefile.txt -- #somefile.txt
%somefile.txt -- %somefile.txt
>somefile.txt -- >somefile.txt
%>#somefile.txt -- %>#somefile.txt
% > #somefile.txt -- somefile.txt
A última linha mostra exatamente o que está acontecendo.
Outro sugeriu usar o piping $f a sed e fazer mágica lá, e isso seria uma boa opção, pois permitiria transformações mais complexas, no entanto assumindo que você só deseja remover os caracteres principais, usando o bash ${PARAMETER#WORD} expansão de parâmetros seria suficiente:
# gpat=" ;for f in *; do echo -- "$f" "${f#$gpat}"; done
Para mim, essa linha resulta em:
>somefile.txt -- somefile.txt
#somefile.txt -- somefile.txt
%somefile.txt -- somefile.txt
%>#somefile.txt -- >#somefile.txt
% > #somefile.txt -- > #somefile.txt
Estou chamando o padrão $gpat como é isso - uma festa padrão de globbing . Não é uma expressão regular.
Observe que ${PAR#WORD} não é voraz e corresponde ao padrão mais curto possível - ${PAR##WORD} corresponde ao padrão mais longo possível. No entanto, com gpat="[%>#]" , isso corresponderá a apenas um caractere:
# gpat="[%>#]" ;for f in *; do echo "$f" -- "${f##$gpat}"; done
%somefile.txt -- somefile.txt
>somefile.txt -- somefile.txt
#somefile.txt -- somefile.txt
%>#somefile.txt -- >#somefile.txt
% > #somefile.txt -- > #somefile.txt
Se tivermos a opção extglob shell configurada (verifique com shopt extglob , defina com shopt -s extglob , desative com shopt -u extglob - provavelmente será definido se você tiver um bashrc razoável), podemos usar a opção estendida padrões de globbing:
# gpat="+([%>#])" ;for f in *; do echo "$f" -- "${f##${gpat}}"; done
%somefile.txt -- somefile.txt
>somefile.txt -- somefile.txt
#somefile.txt -- somefile.txt
%>#somefile.txt -- somefile.txt
% > #somefile.txt -- > #somefile.txt
Notavelmente, em todos os exemplos acima, "% > #somefile.txt" se torna " > #somefile.txt" devido ao espaço após o% não ser capturado pelo padrão.
É claro que ${PARAMETER/PATTERN/STRING} (e o // similar) também aceitam padrões globbing, mas eu só percebi isso (literalmente) enquanto digito essas palavras, e eu realmente não consigo me incomodar em voltar acima para ajustá-lo para refletir isso. De qualquer forma, funciona exatamente da mesma forma e, claro, você só deseja usar PAR/PAT/ para remover caracteres do meio da cadeia.