Eu vi sed 's=.*/=='
no contexto do script sh e estou intrigado. Não consegui encontrar no manual do sed ou na pesquisa na web (para sed s=
) como s
é usado, não s///
. Além de s
ver apenas um comando potencial aqui =
(Imprimir o número da linha de entrada atual), mas nesse caso o que o resto está fazendo ...
A execução do comando no shell produz a mesma saÃda que a entrada para, por exemplo echo 'jkfdsa=335r34'
, , enquanto echo 'jkfdsa=335r34' | sed 's/=.*/==/'
a substituição ocorre conforme o manual. Também modificando ligeiramente o comando para, por exemplo , echo 'jkfdsa=3' | sed 's798=.*/==/'
dar
sed: -e expression #1, char 11: unterminated 's' command
, então original deve ter algum significado correto. O que é isso?
São
=
delimitadores alternativos. Eles são usados ​​porque o padrão contém um/
(que é o delimitador mais comumente usado). Quase qualquer caractere pode ser usado como delimitador alternativo, entãos@.*/@@
ous_.*/__
significaria a mesma coisa. Com o delimitador ordinário, ased
expressão poderia ter sido escrita como(o literal
/
que a expressão deseja corresponder precisa ser escapado aqui) ou, possivelmente mais legÃvel,(a maioria dos caracteres dentro de uma
[...]
classe de caracteres são literais 1 )O que a
sed
expressão faz é substituir qualquer coisa que combine.*/
com nada. Isso terá o efeito de remover tudo até e incluindo o último/
caractere na linha. Ele removerá até o último/
(não o primeiro), pois.*
faz uma correspondência gananciosa de qualquer sequência de caracteres.Exemplo:
O
unterminated 's' command
erro que você recebe ao testaré devido a
7
ser usado como o delimitador para os
comando. A expressãoteria funcionado embora.
1 ... além dos caracteres que têm significado especial dentro
[...]
, como^
(no inÃcio) e-
(quando não for o primeiro, o segundo depois^
ou o último). Os personagens[
e]
também precisam de tratamento especial dentro de[...]
, mas isso foge ao escopo desta questão.Se isso for usado para obter o nome do arquivo no final de um caminho em alguma string ou variável de shell, o
basename
utilitário poderá fazer um trabalho melhor (e também fará a coisa certa se o caminho terminar com uma barra):Da mesma forma, a substituição de parâmetro padrão do shell
${variable##*/}
, supondo que a variável não contenha novas linhas, seria equivalente em seu efeito a passar o valor de$variable
pela expressão acimased
em uma substituição de comando, mas muitas vezes mais rápido.A substituição de variável e o
basename
utilitário também lidam com o manuseio correto de nomes de caminho contendo novas linhas, o quesed
não faria (já que processa sua entrada linha por linha).De https://backreference.org/2010/02/20/using-different-delimiters-in-sed/ :
É um fato não tão conhecido que o sed pode usar qualquer caractere como separador para o comando "s". Basicamente, o sed pega o que segue o "s" como separador.
Assim, a barra no meio torna-se apenas um caractere normal. Se estou interpretando corretamente, sua expressão:
também pode ser escrito como:
e explicado como "remover qualquer coisa antes da última barra, incluindo a barra".
Ele remove avidamente todo o conteúdo antes e
/
a si mesmo.Exemplo:
Resultado :
Aqui
=
serve como delimitador para regex(.*/) e replace( null ).