Substituindo a variável corretamente na função alias

Substituindo a variável corretamente na função alias

Estou tentando criar uma função de alias para remover a linha inserida do arquivo:

function remove_line(){
       line_to_remove="'s/^"$1"$//g'"
       sed -i $(line_to_remove) my_file
}

Por exemplo: remove_line domain.comdeve remover este domínio de um determinado arquivo.

No entanto, parece que o $não é interpretado corretamente. O que estou fazendo de errado?

Responder1

Seu principal problema é que $(line_to_remove)é umsubstituição de comando, ou seja, uma expressão substituída pelo texto gerado pelo comando entre parênteses ( line_to_remove, que eu esperaria que gerasse um erro de "comando não encontrado"). Você provavelmente está querendo usar "$line_to_remove".

No entanto, injetar uma variável shell em uma sedexpressão de substituição não é o ideal, pois coloca muitas condições na string injetada (ela deve ser uma expressão regular válida e não pode conter /etc.)

Em vez disso, sugiro usar grepe gravar o resultado na saída padrão ou em um arquivo temporário que substitua o arquivo original após a execução bem-sucedida de grep, ou você pode deixar sponge(do pacote GNU moreutils) sobrescrever o arquivo original.

remove_lines () {
       grep -v -Fx -e "$1" my_file | sponge my_file
}

As opções usadas grepaqui garantem que a linha fornecida como primeiro argumento da função seja usada como está (não como uma expressão regular), corresponda a uma linha do início ao fim e remova as linhas correspondentes da entrada.

Sem sponge:

remove_lines () {
       tmpfile=$(mktemp)
       grep -v -Fx -e "$1" my_file >"$tmpfile" && mv "$tmpfile" my_file
       rm -f "$tmpfile"
}

O mvé executado somente se grepfor executado com sucesso e rm -fremove o arquivo temporário caso isso não aconteça.


Pessoalmente, eu provavelmente escreveria a função assim:

remove_lines () {
       grep -v -Fx -e "$1"
}

Isso permite que um usuário use-o assim:

remove_lines "my line" <my_file | sponge my_file

some-command | remove_lines "bumble bee" | other-command

Isso faz com que a função funcione como um filtro quesó faz o que diz na lata, ou seja, ele remove linhas da entrada e não se importa de onde a entrada vem ou para onde está indo.

informação relacionada