Estou tentando modificar um caminho armazenado em uma variável ( $var
) através de sed
. Na verdade, preciso substituir $(dirname "$var")
por motivos relacionados ao objetivo do meu roteiro.
Um exemplo de var
is var=/dir/dir xyz/file.txt
, while filename
contém vários caminhos a serem substituídos que podem estar em qualquer posição (uma perto do meio da linha, outra no início, etc). Abaixo tento dar um exemplo de filename
:
dog foo/bar /dir/dir xyz/file.txt
a b c d /dir/dir xyz/file.txt x y z
/dir/dir xyz/file.txt 1234
{[(/dir/dir xyz/file.txt
o que eu quero é
dog foo/bar .
a b c d . x y z
. 1234
{[(.
eu tentei o seguinte
sed "s|"$(dirname "$var")"|.|g" "$filename"
obtendosed: -e expression #1, char 31: unterminated `s' command
Você poderia me ajudar? Claro, você pode sugerir outra maneira além de sed
.
Isso parece ser tudo o que você está tentando fazer, usando qualquer sed e assumindo que sua variável não contém nenhum
:
s:Não sei por que você estava ligando
dirname
. Além disso, se você não estiver indo para nós/
como o delimitador sed, não use um metacaractere regexp como|
isso apenas ofusca seu código na melhor das hipóteses, escolha um caractere como:
sempre literal. E não use nomes de variáveis em maiúsculas para variáveis que não sejam de ambiente, consulte correct-bash-and-shell-script-variable-capitalization .Dado o seu comentário , se você realmente precisar ligar
dirname
por algum motivo, poderá fazer:Em:
O
s|
e|.|g
estão entre aspas, mas o$(dirname "$var")
está fora das aspas e, portanto, está sujeito a split+glob.Corrigiria isso (também adicionando os
--
s ausentes), mas ainda está errado, pois o lado esquerdo dos/lhs/rhs/flags
insed
é interpretado como um regex (sem mencionar que você pode ter sérios problemas se$var
contiver|
caracteres; esed
funciona com texto, enquanto nomes de arquivos não são garantidos).Por exemplo,
.
corresponde a qualquer caractere, não apenas.
.Você deve preferir fazer:
Para que funcione com caminhos de arquivo arbitrários¹.
¹ Estritamente falando para caminhos de arquivo arbitrários, incluindo aqueles que contêm caracteres de nova linha, precisaríamos adicionar a
-0777
opção (modo slurp)perl
e não poderíamos usar a substituição de comando que retira os caracteres de nova linha à direita. Isso pode ser feito passando o full$var
toperl
e use perl'sdirname()
(doFile::Basename
módulo).