¿Qué significa este comando sed?

Oct 16 2020

¿Puede alguien ayudarme a interpretar el siguiente comando Sed de Linux?

 sed -i '' 's#__OPENGL_LIBS__#-lGL -lGLU#' src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro

Admito alegremente que encuentro que la sintaxis de comandos de sed es muy oscura, y leer la página del manual de sed no me ha ayudado mucho hasta ahora. Cuando ejecuto el comando anterior, obtengo este error:

sed: can't read s#__OPENGL_LIBS__#-lGL -lGLU#: No such file or directory

Entonces, obviamente, sed interpreta el tercer argumento como un nombre de archivo: ¿es este el archivo que se va a modificar? Desde la página de manual de sed veo que -Isignifica editar el archivo de destino en su lugar.

El segundo argumento es la cadena vacía ""- la página de manual dice que esto es "script-solo-si-no-otro-script" pero no explica lo que eso significa. El último argumento src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro: sé que un líder s/significa buscar y reemplazar, pero ¿qué src/significa?

Respuestas

2 Giacomo1968 Oct 16 2020 at 09:10

src/es solo el directorio donde qt-mbgrdviz-3/qt-mbgrdviz-3.prodebería estar.

El comando Sed es bastante simple pero, como la mayoría de las líneas de comando, puede parecer más complicado de lo que es.

sed -i "" "s#__OPENGL_LIBS__#-lGL -lGLU#" src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro
  • -i: Significa ejecutar el comando contra archivos en su lugar; lo que significa simplemente sobrescribirlo.
  • "": Sería la extensión de archivo que se utilizará al realizar la edición in situ para las copias de seguridad. Pero como dice la página del manual, "Si se proporciona una extensión de longitud cero, no se guardará ninguna copia de seguridad". Eso básicamente implica que todo lo que sigue a la -Ino es opcional. Entonces, ""efectivamente anula ese valor a una extensión de longitud cero para que las copias de seguridad ya no se guarden. Tenga en cuenta que así es como se usa en BSD (y macOS) y no en las herramientas GNU que usa Linux; en ese caso -isolo sería suficiente.
  • "s#__OPENGL_LIBS__#-lGL -lGLU#": En Sed, todo lo que sigue al primero sdel patrón se utiliza como delimitador. En este caso, reemplazará todas las apariciones de __OPENGL_LIBS__por el valor de -lGL -lGLU.
  • src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro: Esta es simplemente la ruta completa al archivo que se va a sedimentar. Entonces, cuando usted sabe lo que src/significa, es simplemente la ruta del directorio que debe contener qt-mbgrdviz-3/qt-mbgrdviz-3.pro.

Tenga en cuenta que si bien este comando funciona en la versión BSD de Sed que está instalada en sistemas como macOS, fallará en los sistemas GNU debido a la extensión -i "". En sistemas GNU eso -i ""debería ser simplemente -iasí:

sed -i "s#__OPENGL_LIBS__#-lGL -lGLU#" src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro

Sabiendo que parece que su error es intentar ejecutar esa variante BSD del comando con GNU. Mira el error:

sed: can't read s#__OPENGL_LIBS__#-lGL -lGLU#: No such file or directory

Con eso extraño "", Sed en GNU lo interpretaría ""como el comando Sed y pensaría que "s#__OPENGL_LIBS__#-lGL -lGLU#"es la ruta del archivo.


Extra : En los comentarios preguntas:

"¿Alguien sabe cuál es la mejor manera de escribir un autoproceso portátil que use Sed?"

No conozco los detalles de su script o sus objetivos, pero en mis propios scripts Bash, que desarrollo en macOS y luego uso en sistemas Linux también, tengo un fragmento de código como este cerca de la parte superior del guión:

#!/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

Y luego, nuevamente usando su comando de ejemplo, haría algo como esto:

sed ${sed_options} "s#__OPENGL_LIBS__#-lGL -lGLU#" src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro

Tenga en cuenta cómo reemplacé el -i ""/ -icon ${sed_options}. De esa manera, puedo concentrarme en la codificación del script principal cuando codifico en macOS y no tener que preocuparme por las cosas que se ahogan en los sistemas Linux.