Que signifie cette commande sed?

Oct 16 2020

Quelqu'un peut-il m'aider à interpréter la commande Linux Sed suivante?

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

J'admets joyeusement que je trouve la syntaxe de la commande sed très obscure et que la lecture de la page de manuel sed ne m'a pas beaucoup aidé jusqu'à présent. Lorsque j'exécute la commande ci-dessus, j'obtiens cette erreur:

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

Donc, évidemment, sed interprète le troisième argument comme un nom de fichier - est-ce le fichier à modifier? Dans la page de manuel sed, je vois que cela -Isignifie modifier le fichier cible sur place.

Le deuxième argument est la chaîne vide ""- la page de manuel dit que c'est "script-only-if-no-other-script" mais n'explique pas ce que cela signifie. Le dernier argument src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro- je sais qu'un leader s/signifie trouver et remplacer, mais qu'est-ce que cela src/signifie?

Réponses

2 Giacomo1968 Oct 16 2020 at 09:10

src/est juste le répertoire où qt-mbgrdviz-3/qt-mbgrdviz-3.prodevrait être.

La commande Sed est assez simple mais - comme la plupart des choses en ligne de commande - peut sembler plus compliquée qu'elle ne l'est.

sed -i "" "s#__OPENGL_LIBS__#-lGL -lGLU#" src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro
  • -i: Signifie exécuter la commande sur les fichiers en place; ce qui signifie simplement l'écraser.
  • "": Ce serait l'extension de fichier à utiliser lors de l'édition sur place pour les sauvegardes. Mais comme le dit la page de manuel, "Si une extension de longueur nulle est donnée, aucune sauvegarde ne sera enregistrée." Cela implique essentiellement que tout ce qui suit -In'est pas facultatif. Ainsi, ""cette valeur annule effectivement cette valeur en une extension de longueur nulle afin que les sauvegardes ne soient plus enregistrées. Notez que c'est ainsi qu'il est utilisé sur BSD (et macOS) et non sur les outils GNU utilisés par Linux; dans ce cas -iseul suffirait.
  • "s#__OPENGL_LIBS__#-lGL -lGLU#": Dans Sed, tout ce qui suit le premier sdu modèle est utilisé comme délimiteur. Dans ce cas, il remplacera toute / toutes les occurrences de __OPENGL_LIBS__par la valeur de -lGL -lGLU.
  • src/qt-mbgrdviz-3/qt-mbgrdviz-3.pro: Il s'agit simplement du chemin d'accès complet au fichier à déduire. Donc, quand vous dites ce que src/signifie, c'est simplement le chemin du répertoire qui doit contenir qt-mbgrdviz-3/qt-mbgrdviz-3.pro.

Notez que même si cette commande fonctionne sur la version BSD de Sed installée sur des systèmes tels que macOS, elle échouera sur les systèmes GNU en raison de l'extension -i "". Sur les systèmes GNU, cela -i ""devrait simplement -iressembler à ceci:

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

Sachant qu'il semble que votre erreur tente d'exécuter cette variante BSD de la commande avec GNU. Regardez l'erreur:

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

Avec cela étranger "", Sed sur GNU interpréterait cela ""comme la commande Sed et penserait que "s#__OPENGL_LIBS__#-lGL -lGLU#"c'est le chemin du fichier.


Extra : Dans les commentaires, vous demandez:

"Quelqu'un sait-il comment écrire au mieux un autoscript portable utilisant Sed?"

Je ne connais pas les spécificités de votre script ni ses objectifs, mais dans mes propres scripts Bash - que je développe sous macOS puis que j'utilise également sur les systèmes Linux, j'ai un morceau de code comme celui-ci en haut de la page scénario:

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

Et puis - à nouveau en utilisant votre exemple de commande - je ferais quelque chose comme ceci:

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

Notez comment j'ai remplacé le -i ""/ -ipar ${sed_options}. De cette façon, je peux me concentrer sur le codage de scripts de base lorsque je code sur macOS et ne pas avoir à me soucier des problèmes d'étouffement sur les systèmes Linux.