No meu bash
script eu tenho uma string e seu prefixo / sufixo. Preciso remover o prefixo / sufixo da string original.
Por exemplo, digamos que tenho os seguintes valores:
string="hello-world"
prefix="hell"
suffix="ld"
Como chego ao seguinte resultado?
result="o-wor"
Respostas:
fonte
${${string#prefix}%suffix}
mas não funciona.Usando sed:
Dentro do comando sed, o
^
caractere corresponde ao texto que começa com$prefix
, e o final$
corresponde ao texto que termina com$suffix
.Adrian Frühwirth faz bons comentários nos comentários abaixo, mas
sed
com esse objetivo pode ser muito útil. O fato de o conteúdo do prefixo $ e do sufixo $ ser interpretado pelo sed pode ser bom ou ruim - desde que você preste atenção, você deve estar bem. A beleza é que você pode fazer algo assim:que pode ser o que você deseja e é mais sofisticado e mais poderoso que a substituição de variáveis do bash. Se você se lembra que com grande poder vem uma grande responsabilidade (como o Homem-Aranha diz), você deve ficar bem.
Uma rápida introdução ao sed pode ser encontrada em http://evc-cit.info/cit052/sed_tutorial.html
Uma observação sobre o shell e seu uso de strings:
Para o exemplo específico dado, o seguinte também funcionaria:
... mas apenas porque:
Geralmente, é uma boa prática citar uma sequência na linha de comando porque, mesmo que contenha espaços, ela será apresentada ao comando como um único argumento. Citamos o prefixo $ e o sufixo $ pelo mesmo motivo: cada comando de edição para sed será passado como uma sequência. Usamos aspas duplas porque elas permitem interpolação variável; se tivéssemos usado aspas simples, o comando sed teria obtido um literal
$prefix
e$suffix
que certamente não é o que queríamos.Observe também o uso de aspas simples ao definir as variáveis
prefix
esuffix
. Certamente, não queremos que nada nas seqüências seja interpretado, por isso as aspas simples, para que não ocorra interpolação. Novamente, pode não ser necessário neste exemplo, mas é um hábito muito bom entrar.fonte
$string
está sujeito a divisão de palavras e globbing. 2)$prefix
e$suffix
pode conter expressões quesed
interpretarão, por exemplo, expressões regulares ou o caractere usado como delimitador, que interromperá todo o comando. 3)sed
Não é necessário ligar duas vezes (você pode-e 's///' -e '///'
) e o tubo também pode ser evitado. Por exemplo, considerestring='./ *'
e / ouprefix='./'
veja-o quebrar horrivelmente devido a1)
e2)
./
, então useised "s#^$prefix##
. (Fragilidade: nomes de arquivo não pode conter#
Desde que eu controlar os arquivos, estamos seguros, não..)#
como delimitador do sed significava que você não podia lidar com arquivos que continham esse personagem.Você sabe o tamanho do seu prefixo e sufixo? No seu caso:
Ou mais geral:
Mas a solução de Adrian Frühwirth é muito legal! Eu não sabia disso!
fonte
Eu uso grep para remover prefixos de caminhos (que não são bem tratados por
sed
):\K
remove da partida todos os caracteres anteriores.fonte
grep -P
é uma extensão não padrão. Mais poder para você, se ele é suportado em sua plataforma, mas esse é um conselho duvidoso se seu código precisar ser razoavelmente portátil.grep
. Versões anteriores realmente tinham a-P
opção do BSD,grep
mas a removeram.Notas:
# $ prefix: adicionando # garante que a subcadeia "hell" seja removida somente se for encontrada no início. Sufixo% $: adicionar% garante que a subcadeia "ld" seja removida apenas se for encontrada no final.
Sem eles, os substrings "hell" e "ld" serão removidos em todos os lugares, mesmo que sejam encontrados no meio.
fonte
/
logo após a string, para que serve?Usando o
=~
operador :fonte
Solução pequena e universal:
fonte
expr
-lo. Era uma espécie de utilidade conveniente para pia de cozinha nos dias da concha Bourne original, mas agora está muito além da data de validade.Usando a resposta @Adrian Frühwirth:
use assim
fonte
Eu usaria grupos de captura no regex:
((?:(?!(${suffix})).)*)
garante que o conteúdo de${suffix}
será excluído do grupo de captura. Em termos de exemplo, é a string equivalente a[^A-Z]*
. Caso contrário, você receberá:fonte