tl, dr:
Uso:
sed -i 's:"\.\./\.\./\.\./Plumed\.h":"/usr/local/include/Plumed.h":g' ../dist0.xvg
Alguns comentários sobre sua tentativa de comando Sed:
sed -i '/../../../Plumed.h/c\/usr/local/include/Plumed.h' ../dist0.xvg
-
-i
não é portátil, então parece que você está usando o GNU Sed.
O BSD Sed também possui uma opção -i
, mas a extensão de backup é um argumento obrigatório, portanto, para modificar um arquivo sem salvar um backup no BSD Sed, é necessário -i ''
.
Outras versões do Sed podem não ter nenhuma mudança -i
.
-
O regex aqui, /../../../Plumed.h/
, contém várias cópias do delimitador regex.
A solução usual para isso é escapar do delimitador:
/..\/..\/..\/Plumed.h/
No entanto, há um fato pouco conhecido sobre Sed, que você pode usar qualquer caractere para o delimitador regex (não apenas no comando s
) se você ignorar a primeira instância da barra invertida . (Bem, quase qualquer - barra invertida ou nova linha não é permitida).
Para citar as especificações POSIX diretamente:
In a context address, the construction "\cBREc
", where c is any character other than <backslash>
or <newline>
, shall be identical to "/BRE/
". If the character designated by c appears following a <backslash>
, then it shall be considered to be that literal character, which shall not terminate the BRE. For example, in the context address "\xabc\xdefx
", the second x stands for itself, so that the BRE is "abcxdef
".
Portanto, para evitar a "síndrome da paleta inclinada", observe que as duas expressões regulares a seguir são equivalentes:
/..\/..\/..\/Plumed.h/
\:../../../Plumed.h:
Note que eu disse "equivalente", não correto. Isso me leva ao próximo ponto, perdido em todas as outras respostas:
-
Um período ( .
) em uma expressão regular significa qualquer caractere .
Se você quiser corresponder apenas a um período literal, pode fugir do período com uma barra invertida ou colocá-lo em uma classe de caractere como em [.]
.
Assim, para corresponder apenas a períodos literais, o regex deve ser mais parecido com:
\:\.\./\.\./\.\./Plumed\.h:
Tanto para evitar palitos inclinados.
Você também pode usar o formato mais legível:
\:[.][.]/[.][.]/[.][.]/Plumed[.]h:
-
O comando c
altera a linha inteira , não apenas a parte da linha correspondida pela expressão regular.
Use o comando s
para alterar apenas uma parte de uma linha.
Notavelmente, com o comando s
, você não precisa escapar do primeiro delimitador de regex (mesmo para um caractere incomum usado como um delimitador) da maneira como você faz ao usar um delimitador alternativo em um endereço.
Além disso, com relação ao comando c
, vale a pena saber que incluir o novo texto na mesma linha que o c\
é uma extensão GNU e não portável.
Colocando tudo isso junto, você pode usar o comando s
da seguinte forma:
sed -i 's:"\.\./\.\./\.\./Plumed\.h":"/usr/local/include/Plumed.h":g' ../dist0.xvg
Ou, se quiser ser ainda mais explícito, use uma regex ancorada e o comando c
hange para alterar apenas a linha inteira:
sed -i '\:^#include "\.\./\.\./\.\./Plumed\.h"$:c\#include "/usr/local/include/Plumed.h"' ../dist0.xvg