Remplacer \ n par une nouvelle ligne dans sed portablement
23
Je suis tellement confus avec GNU sed, POSIX sedet sedla myriade d'options de BSD . Comment remplacer le littéral \npar le caractère de nouvelle ligne en utilisant ces trois sedtypes?
Est-ce que cela fonctionne pour toutes sortes de sed?
Avinash Raj
Je pense que oui; J'ai testé uniquement sur Linux en utilisant la version gnu.
unxnut
11
@AvinashRaj. C'est POSIX et a travaillé avec la sedcommande d' origine dans Unix v7 en 1979. Le seul endroit où cela pourrait ne pas fonctionner serait des implémentations non POSIX allégées sedcomme certaines implémentées allégées basées sur la boîte occupée. Cela ne fonctionnera pas dans csh mais c'est un problème csh.
Stéphane Chazelas
Puisque \\nest utilisé dans la partie recherche, pourquoi ne pas l'utiliser \ndans le remplacement? le premier semble impliquer que le second existe. c'est à dire. pourquoi pas$ echo '1\n2'|sed 's/\\n/\n/g'
Dans ce cas, \nest un littéral, ce qui implique qu'il apparaît comme les deux caractères: abackslash suivi de n, et non comme un seul caractère de nouvelle ligne. Par conséquent, deux barres obliques inverses pour faire de la barre oblique inverse un littéral, puisn
unxnut
9
Puisque vous avez déjà votre sedréponse portable , je mentionnerai simplement que sedc'est rarement le meilleur outil si vous devez en quelque sorte manipuler des nouvelles lignes. Perl est presque aussi portable que sed, est installé par défaut sur la plupart des systèmes * nix et peut gérer cela très facilement:
Sur Solaris, n'oubliez pas d'utiliser le awk standard dans / usr / xpg4 / bin, celui dans / bin est un historique et ne doit pas être utilisé pour les nouveaux scripts.
Je dirais que awka des problèmes de portabilité similaires (est ma awkplaine vieux awk, nawkou gawk?). En fait, la version de mes boîtiers Solaris manque gsub(). Mon vote ici est pour Perl (se perl -nlawe '...'rapproche du comportement automatique de awk).
arielCo
2
@arielCo: Pour la awkportabilité, restez avec une version awkcompatible POSIX et n'utilisez que ces fonctionnalités et tout devrait bien se passer. Sur Solaris, vous en trouverez un en tant que /usr/xpg4/bin/awk.
@arielCo en fait, awk est plus portable que perl. Ma deuxième approche awk qui n'utilise pas gsub()devrait fonctionner à peu près partout. Même busybox a un awk.
terdon
1
gsub () est POSIX (gsub, a été ajouté dans SVR3.1, POSIX awk est basé sur SVR4 avec quelques ajouts voir le manuel de gawk pour plus d'informations), gensub () est l'extension GNU. L'awk d'origine toujours trouvé sous / bin / awk sur Solaris, ne supportait pas non plus la prise en charge de gsub (), mais ne supportait pas non plus un FS à plusieurs caractères.
Stéphane Chazelas
1
Si Holdspace est vide, vous pouvez également faire:
sed '/\\n/G;s/\\n\(.*\)\(.\)/\2\1/;P;D'
... mais la réponse de uxnut est déjà à la fois plus rapide et plus simple, vous pouvez donc la prendre comme bon vous semble .
Une autre possibilité étrangère:
INPUT | sed -n l | while read v ; do printf "${v%?}" ; done
Mais attention, ^ qui traduit toutes les \échappements antislash de style C standard - comme \backspace et \return et \00octals et whathaveyou.
Vous avez besoin d'une solution dans sed, qui est déjà donnée ci-dessous. Mais je voulais ajouter une autre possibilité que IMHO est juste plus facile et plus rapide,
foo\\nbar
oufoo\\\nbar
?Réponses:
Remarquez la barre oblique inverse juste avant d'appuyer sur return dans la chaîne de remplacement.
la source
sed
commande d' origine dans Unix v7 en 1979. Le seul endroit où cela pourrait ne pas fonctionner serait des implémentations non POSIX allégéessed
comme certaines implémentées allégées basées sur la boîte occupée. Cela ne fonctionnera pas dans csh mais c'est un problème csh.\\n
est utilisé dans la partie recherche, pourquoi ne pas l'utiliser\n
dans le remplacement? le premier semble impliquer que le second existe. c'est à dire. pourquoi pas$ echo '1\n2'|sed 's/\\n/\n/g'
\n
est un littéral, ce qui implique qu'il apparaît comme les deux caractères: abackslash suivi den
, et non comme un seul caractère de nouvelle ligne. Par conséquent, deux barres obliques inverses pour faire de la barre oblique inverse un littéral, puisn
Puisque vous avez déjà votre
sed
réponse portable , je mentionnerai simplement quesed
c'est rarement le meilleur outil si vous devez en quelque sorte manipuler des nouvelles lignes. Perl est presque aussi portable quesed
, est installé par défaut sur la plupart des systèmes * nix et peut gérer cela très facilement:Un autre choix très portable est
awk
:Sur Solaris, n'oubliez pas d'utiliser le awk standard dans / usr / xpg4 / bin, celui dans / bin est un historique et ne doit pas être utilisé pour les nouveaux scripts.
la source
awk
a des problèmes de portabilité similaires (est maawk
plaine vieuxawk
,nawk
ougawk
?). En fait, la version de mes boîtiers Solaris manquegsub()
. Mon vote ici est pour Perl (seperl -nlawe '...'
rapproche du comportement automatique deawk
).awk
portabilité, restez avec une versionawk
compatible POSIX et n'utilisez que ces fonctionnalités et tout devrait bien se passer. Sur Solaris, vous en trouverez un en tant que/usr/xpg4/bin/awk
.echo "aa\nbb" | awk '{gsub(/\\n/,"\n");}1;'
?gsub()
devrait fonctionner à peu près partout. Même busybox a unawk
.Si
H
oldspace est vide, vous pouvez également faire:... mais la réponse de uxnut est déjà à la fois plus rapide et plus simple, vous pouvez donc la prendre comme bon vous semble .
Une autre possibilité étrangère:
Mais attention, ^ qui traduit toutes les
\
échappements antislash de style C standard - comme\b
ackspace et\r
eturn et\00
octals et whathaveyou.la source
Avec
gnu sed
les éléments suivants fonctionne également:la source
Vous avez besoin d'une solution dans sed, qui est déjà donnée ci-dessous. Mais je voulais ajouter une autre possibilité que IMHO est juste plus facile et plus rapide,
la source