Existe-t-il une invocation de la sed
modification sur place des tâches sans sauvegardes qui fonctionne à la fois sur Linux et Mac? Alors que le BSD sed
livré avec OS X semble avoir besoin sed -i '' …
, les distributions GNU sed
Linux sont généralement fournies avec les citations comme nom de fichier d'entrée vide (au lieu de l'extension de sauvegarde), et en ont sed -i …
plutôt besoin .
Existe-t-il une syntaxe de ligne de commande qui fonctionne avec les deux versions, donc je peux utiliser le même script sur les deux systèmes?
Réponses:
Si vous voulez vraiment simplement utiliser
sed -i
la méthode «facile», les éléments suivants fonctionnent sur GNU et BSD / Macsed
:Notez le manque d'espace et le point.
Preuve:
Évidemment, vous pouvez alors simplement supprimer les
.bak
fichiers.la source
sed
)sed
n'accepte pas de positioncommand
argument lorsque invoqué avec-i
- il doit être fourni avec un autre drapeau,-e
. Ainsi, la commande devient:sed -i.bak -e 's/foo/bar/' filename
sed -i.bak 's/foo/bar/' file && rm file.bak
Cela fonctionne avec GNU sed, mais pas sous OS X:
Cela fonctionne sous OS X, mais pas avec GNU sed:
Sous OS X, vous
sed -i -e
car l'extension du fichier de sauvegarde serait définie sur-e
sed -i'' -e
pour les mêmes raisons - il a besoin d'un espace entre-i
et''
.la source
-i
et-i''
sont identiques au moment de l'analyse du shell;sed
ne peut pas se comporter différemment sur ces deux premières invocations, car il obtient exactement les mêmes arguments.Sous OSX, j'installe toujours la version GNU sed via Homebrew, pour éviter les problèmes dans les scripts, car la plupart des scripts ont été écrits pour les versions GNU sed.
Ensuite, votre BSD sed sera remplacé par GNU sed.
Alternativement, vous pouvez installer sans noms par défaut, mais ensuite:
PATH
comme indiqué après l'installationgnu-sed
gsed
ou ensed
fonction de votre systèmela source
--with-default-names
été supprimé de homebrew-core , plus d'informations dans cette réponse. lors de l'installationgnu-sed
maintenant, les instructions d'installation spécifient que vous devez ajoutergnubin
à votrePATH
:PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"
Comme le demande Noufal Ibrahim , pourquoi ne pouvez-vous pas utiliser Perl? Tout Mac aura Perl, et il y a très peu de distributions Linux ou BSD qui n'incluent pas de version de Perl dans le système de base. L'un des seuls environnements qui pourrait manquer de Perl serait BusyBox (qui fonctionne comme GNU / Linux pour
-i
, sauf qu'aucune extension de sauvegarde ne peut être spécifiée).Comme le recommande ismail ,
et cela semble être une meilleure solution dans presque tous les cas que les scripts, les alias ou d'autres solutions de contournement pour faire face à l'incompatibilité fondamentale
sed -i
entre GNU / Linux et BSD / Mac.la source
perl
fait partie de la spécification Linux Standard Base depuis le 1er mai 2009. refspecs.linuxfoundation.org/LSB_4.0.0/LSB-Languages/…Il n'y a aucun moyen de le faire fonctionner.
Une façon consiste à utiliser un fichier temporaire comme:
Cela fonctionne à la fois
la source
Réponse: non
La réponse initialement acceptée ne fait pas ce qui est demandé (comme indiqué dans les commentaires). (J'ai trouvé cette réponse en cherchant la raison pour laquelle
file-e
a apparaissait "au hasard" dans mes répertoires.)Il n'y a apparemment aucun moyen de
sed -i
travailler de manière cohérente sur MacOS et Linuces.Ma recommandation, pour ce qu'elle vaut, n'est pas de mettre à jour sur place
sed
(qui a des modes de défaillance complexes), mais de générer de nouveaux fichiers et de les renommer ensuite. En d'autres termes: évitez-i
.la source
L'
-i
option ne fait pas partie de POSIX Sed . Une méthode plus portable serait d'utiliser Vim en mode Ex:%
sélectionner toutes les ligness
remplacerx
sauver et fermerla source
Voici une autre version qui fonctionne sur Linux et macOS sans utiliser
eval
et sans avoir à supprimer les fichiers de sauvegarde. Il utilise des tableaux Bash pour stocker lessed
paramètres, ce qui est plus propre que d'utilisereval
:Cela ne crée pas de fichier de sauvegarde, ni un fichier avec des guillemets ajoutés.
la source
sedi=(-i) && [ "$(uname)" == "Darwin" ] && sedi=(-i '')
sed "${sedi[@]}" -e 's/foo/bar/' target.file
La réponse de Steve Powell est tout à fait correcte, la consultation de la page MAN de sed sur OSX et Linux (Ubuntu 12.04) met en évidence la non-compatibilité dans l'utilisation sed sur place entre les deux systèmes d'exploitation.
JFYI, il ne devrait y avoir aucun espace entre le -i et les guillemets (qui dénotent une extension de fichier vide) utilisant la version Linux de sed, donc
Page de manuel Linux sed
et
page de manuel sed OSX
J'ai contourné cela dans un script en utilisant une commande alias et la sortie du nom du système d'exploitation de « uname » dans un bash «if». La tentative de stockage des chaînes de commande dépendant du système d'exploitation dans des variables a été aléatoire lors de l'interprétation des guillemets. L'utilisation de ' shopt -s expand_aliases ' est nécessaire pour développer / utiliser les alias définis dans votre script. l'utilisation de shopt est traitée ici .
la source
Si vous avez besoin de faire
sed
sur place dans unbash
script, et que vous ne voulez PAS que le résultat sur place avec des fichiers .bkp, et vous avez un moyen de détecter le système d'exploitation (par exemple, en utilisant ostype.sh ), - alors le le hack suivant avec lebash
shell intégréeval
devrait fonctionner:la source
Vous pouvez utiliser une éponge. Sponge est un ancien programme Unix, trouvé dans le paquet moreutils (à la fois dans Ubuntu et probablement Debian, et dans Homebrew sous Mac).
Il mettra en mémoire tampon tout le contenu du tuyau, attendra que le tuyau soit fermé (ce qui signifie probablement que le fichier d'entrée est déjà fermé), puis écrasera:
Depuis la page de manuel :
la source
Ce qui suit fonctionne pour moi sur Linux et OS X:
sed -i' ' <expr> <file>
par exemple pour un fichier
f
contenantaaabbaaba
sed -i' ' 's/b/c/g' f
rendements
aaaccaaca
sur Linux et Mac. Notez qu'il existe une chaîne entre guillemets contenant un espace , sans espace entre les-i
et la chaîne. Les guillemets simples ou doubles fonctionnent tous les deux.Sous Linux, j'utilise la
bash
version 4.3.11 sous Ubuntu 14.04.4 et sur la version Mac 3.2.57 sous OS X 10.11.4 El Capitan (Darwin 15.4.0).la source
J'ai rencontré ce problème. La seule solution rapide a été de remplacer le sed en mac par la version gnu:
la source