Como usar o sed para gravar em um nome de arquivo armazenado em uma variável?

4

De dentro de um script bash , como posso usar sed para gravar em um arquivo onde o nome do arquivo é armazenado em uma variável bash? O redirecionamento de saída não funciona porque quero editar um arquivo no lugar, puxando as linhas que correspondem a um regex para um arquivo diferente e excluindo-as no primeiro arquivo.

Algo como:

sed -i '/^my regex here$/{;w file2;d;}' file1

... mas onde file1 e file2 são realmente variáveis que retêm os nomes dos arquivos. (Como file2=$(mktemp) .)

Então, o que eu realmente quero é expansão de variável para o nome do arquivo, mas nenhuma expansão para o restante do comando sed , e deixar a coisa toda como um único argumento passado para o comando sed .

Por qualquer motivo, o seguinte não funciona:

sed -i '/my regex here/{;w '"$file2"';d;}' $file1

Ele diz "inigualável {" e não consigo entender o motivo.

De alguma forma eu posso fazer isso?

    
por Wildcard 03.11.2015 / 01:17

3 respostas

3

Como você está usando uma única expressão sed , tudo o que segue depois do w (incluindo o } ) é interpretado como o nome wfile :

The argument wfile shall terminate the editing command.

Você pode ver isso se adicionar um segundo comando } , por exemplo como:

sed -e '/my regex here/{w '"$file2"';d;}' -e '}' $file1

, as linhas correspondentes a my regex here serão salvas em um arquivo chamado whatever;d;} , em que whatever é o que quer que $file1 expanda para. A sintaxe correta é através de comandos separados, com várias expressões:

sed -e '/my regex here/{w '"$file1" -e 'd' -e '}' $file2

ou um comando por linha:

sed '/my regex here/{
w '"$file1"'
d
}
' $file2
    
por 03.11.2015 / 03:06
3

Encontrei a resposta em Stackoverflow em "Como faço para permitir que o comando sed 'w' saiba onde o nome do arquivo termina? "

Como Terdon apontou, o problema não é a variável - mas também não tem nada a ver com chaves; tente sed '/^l/w testing;p' e você verá que ele não gera nenhum erro, mas grava todas as linhas que começam com l em um arquivo chamado testing;p .

O problema é, na verdade, a falta de uma nova linha após o nome do arquivo.

Portanto, a resposta é usar uma nova linha inline no comando sed:

sed -i '/my regex here/{;w '"$file2"'
d;}' $file1

Ou , o que é muito mais limpo, use dois argumentos -e separados:

sed -i -e '/my regex here/{;w '"$file2" -e 'd;}' $file1

Se você não gosta das duas citações adjacentes (as quais você pode facilmente inserir), basta colocar o comando write em seu próprio argumento:

sed -i -e '/^my regex here$/{' -e "w $file2" -e 'd;}' $file1
    
por 03.11.2015 / 02:55
-1

Use as aspas duplas em vez das únicas para citar o comando sed. E não se esqueça de escapar de personagens adequados.

Mais informações sobre como citar variáveis no bash neste link

    
por 03.11.2015 / 01:55

Tags