GNU/Linux >> Tutoriels Linux >  >> Linux

Comment atteindre la portabilité avec Sed -i (édition sur place) ?

J'écris des scripts shell pour mon serveur, qui est un hébergement mutualisé exécutant FreeBSD. Je veux aussi pouvoir les tester en local, sur mon PC sous Linux. Par conséquent, j'essaie de les écrire de manière portable, mais avec sed Je ne vois aucun moyen de le faire.

Une partie de mon site Web utilise des fichiers HTML statiques générés, et cette ligne sed insère le DOCTYPE correct après chaque régénération :

sed -i '1s/^/<!DOCTYPE html> n/' ${file_name.html}

Cela fonctionne avec GNU sed sous Linux, mais FreeBSD sed attend le premier argument après -i possibilité d'être une extension pour la copie de sauvegarde. Voici à quoi cela ressemblerait :

sed -i '' '1s/^/<!DOCTYPE html> n/' ${file_name.html}

Cependant, GNU sed attend à son tour que l'expression suive immédiatement après -i .
(Cela nécessite également des correctifs avec la gestion des sauts de ligne, mais cela a déjà été répondu ici)

Bien sûr, je peux inclure ce changement dans ma copie serveur du script, mais cela gâcherait, c'est-à-dire mon utilisation de VCS pour la gestion des versions. Existe-t-il un moyen d'y parvenir avec sed de manière entièrement portable ?

Réponse acceptée :

GNU sed accepte une extension facultative après -i . L'extension doit être dans le même argument sans espace intermédiaire. Cette syntaxe fonctionne également sur BSD sed.

sed -i.bak -e '…' SOMEFILE

Notez que sur BSD, -i modifie également le comportement lorsqu'il y a plusieurs fichiers d'entrée :ils sont traités indépendamment (par exemple, $ correspond à la dernière ligne de chaque fichier). De plus, cela ne fonctionnera pas sur BusyBox.

Si vous ne souhaitez pas utiliser de fichiers de sauvegarde, vous pouvez vérifier quelle version de sed est disponible.

case $(sed --help 2>&1) in
  *GNU*) set sed -i;;
  *) set sed -i '';;
esac
"[email protected]" -e '…' "$file"

Ou bien, pour éviter d'écraser les paramètres positionnels, définissez une fonction.

case $(sed --help 2>&1) in
  *GNU*) sed_i () { sed -i "[email protected]"; };;
  *) sed_i () { sed -i '' "[email protected]"; };;
esac
sed_i -e '…' "$file"

Si vous ne voulez pas vous embêter, utilisez Perl.

perl -i -pe '…' "$file"

Si vous voulez écrire un script portable, n'utilisez pas -i - ce n'est pas dans POSIX. Faites manuellement ce que sed fait sous le capot : il ne s'agit que d'une ligne de code de plus.

sed -e '…' "$file" >"$file.new"
mv -- "$file.new" "$file"

Linux
  1. Comment utiliser la commande Sed sous Linux avec des exemples

  2. Comment remplacer une chaîne dans un ou plusieurs fichiers ?

  3. Ajout avec "sed" ?

  4. Comment utiliser Sed ou Ex pour remplacer un bloc (code multiligne) par un nouveau bloc de texte (code) ?

  5. Comment remplacer sed comme texte par python?

Comment intégrer ONLYOFFICE 9.6 à WordPress

Comment sécuriser les serveurs Linux avec SE Linux

COMMENT UTILISER L'EDITEUR SED

Comment créer un e-commerce avec Magento

Comment remplacer récursivement les caractères par sed ?

Comment modifier un fichier sur place en utilisant awk ? (comme avec sed -i)