O que esse comando sed significa?
Alguém pode me ajudar a interpretar o seguinte comando Linux Sed?
sed -i '' 's#__OPENGL_LIBS__#-lGL -lGLU#' src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro
Eu admito alegremente que acho a sintaxe do comando sed muito obscura, e ler a página de manual do sed não me ajudou muito até agora. Quando executo o comando acima, recebo este erro:
sed: can't read s#__OPENGL_LIBS__#-lGL -lGLU#: No such file or directory
Obviamente, o sed interpreta o terceiro argumento como um nome de arquivo - este é o arquivo a ser modificado? Na página de manual do sed, vejo que -Isignifica editar o arquivo de destino no local.
O segundo argumento é a string vazia ""- a página do manual diz que isso é "script-only-if-nenhum-outro-script", mas não explica o que isso significa. O último argumento src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro- eu sei que um líder s/significa localizar e substituir, mas o que src/significa?
Respostas
src/é apenas o diretório onde qt-mbgrdviz-3/qt-mbgrdviz-3.prodeveria estar.
O comando Sed é bastante simples, mas - como a maioria das coisas de linha de comando - pode parecer mais complicado do que é.
sed -i "" "s#__OPENGL_LIBS__#-lGL -lGLU#" src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro
-i: Significa executar o comando em arquivos no local; significando apenas substituí-lo."": Seria a extensão de arquivo a ser usada ao fazer a edição local para backups. Mas, como diz a página do manual, “Se uma extensão de comprimento zero for fornecida, nenhum backup será salvo.” Isso basicamente implica que tudo o que segue o-Inão é opcional. Portanto, o""valor efetivamente anula para uma extensão de comprimento zero para que os backups não sejam mais salvos. Observe que é assim que ele é usado no BSD (e macOS) e não nas ferramentas GNU usadas pelo Linux; nesse caso,-isó seria suficiente."s#__OPENGL_LIBS__#-lGL -lGLU#": No Sed, tudo o que segue o primeirosno padrão é usado como um delimitador. Nesse caso, ele substituirá qualquer / todas as ocorrências de__OPENGL_LIBS__pelo valor de-lGL -lGLU.src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro: Este é simplesmente o caminho completo para o arquivo a ser sedado. Então, quando você quersrc/dizer, é simplesmente o caminho do diretório que deve conterqt-mbgrdviz-3/qt-mbgrdviz-3.pro.
Observe que, embora esse comando funcione na versão BSD do Sed que está instalado em sistemas como o macOS, ele falhará em sistemas GNU devido ao -i "". Em sistemas GNU que -i ""devem ser simplesmente -iassim:
sed -i "s#__OPENGL_LIBS__#-lGL -lGLU#" src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro
Saber que parece que seu erro é tentar executar aquela variante BSD do comando com GNU. Veja o erro:
sed: can't read s#__OPENGL_LIBS__#-lGL -lGLU#: No such file or directory
Com esse estranho "", o Sed no GNU interpretaria isso ""como o comando Sed e pensaria que esse "s#__OPENGL_LIBS__#-lGL -lGLU#"é o caminho do arquivo.
Extra : Nos comentários você pergunta:
“Alguém sabe a melhor forma de escrever um autoscript portátil que usa Sed?”
Não sei os detalhes de seu script ou seus objetivos, mas em meus próprios scripts Bash - que desenvolvo no macOS e uso em sistemas Linux também, tenho um pedaço de código como este próximo ao topo do roteiro:
#!/bin/bash -l
################################################################################
# Set script variables based on OS specific values.
if [[ "$OSTYPE" =~ ^darwin ]]; then
# For macOS
sed_options='-i ""';
else
# For Linux
sed_options='-i';
fi
E então - novamente usando seu comando de exemplo - eu faria algo assim:
sed ${sed_options} "s#__OPENGL_LIBS__#-lGL -lGLU#" src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro
Observe como substituí -i ""/ -ipor ${sed_options}. Dessa forma, posso me concentrar na codificação do script principal quando codifico no macOS e não preciso me preocupar com problemas em sistemas Linux.