Je trouve que \n
cela ne fonctionne pas dans sed sous Mac OS X. Plus précisément, disons que je veux séparer les mots séparés par un seul espace en lignes:
# input
foo bar
J'utilise,
echo "foo bar" | sed 's/ /\n/'
Mais le résultat est stupide, le \n
n'est pas échappé!
foonbar
Après avoir consulté Google, j'ai trouvé une solution de contournement :
echo 'foo bar' | sed -e 's/ /\'$'\n/g'
Après avoir lu l'article, je ne comprends toujours pas ce que \'$'\n/g'
signifie. Quelqu'un peut-il me l'expliquer ou s'il existe un autre moyen de le faire? Merci!
echo "foo bar" | tr ' ' '\n'
\n
.Réponses:
Vous pouvez
brew install gnu-sed
remplacer les appelssed
avecgsed
.Si vous ne voulez pas ajouter le "g" à la fin
sed
, vous pouvezbrew install gnu-sed --with-default-names
et simplement appelersed
.(Edit: drapeau de brassage mis à jour, pointe de chapeau à Clément.)
la source
--with-default-names
et non--default-names
. Cependant, cette option n'a pas travaillé sur mon installation, donc je devais mettrealias gsed=sed
dans ma~/.profile
pour le faire fonctionner.sed
sur OS X se comporte comme il le fait et fait l'hypothèse incorrecte quignu-sed
est plus correcte. Ne soyez pas un dépendant de GNU et respectez les normes POSIX pour éviter les problèmes à long terme.Ceux-ci fonctionneraient également:
echo 'foo bar' | sed $'s/ /\\\n/g'
lf=$'\n'; echo 'foo bar' | sed "s/ /\\$lf/g"
Sed d'OS X n'interprète pas
\n
le motif de remplacement, mais vous pouvez utiliser un saut de ligne littéral précédé d'un caractère de continuation de ligne. Le shell est remplacé$'\n'
par un saut de ligne littéral avant l'exécution de la commande sed.la source
sed $'s/ /\\\n/g'
travaille- t-il , mais passed $'s/\\\n/ /g'
?sed
linux / unix pour supprimer les nouvelles lignes car elles sont analysées / divisées à chaque nouvelle ligne. Si vous utilisez ceci sous linux / unix, cela ne fera rien non plus:echo -e 'foo\nbar' | sed 's/\n//'
La solution de contournement trouvée passe une chaîne d'argument unique
sed -e
.Cet argument finit par être une chaîne dans le
s/ / /g
format sed habituel .Cette chaîne est créée en deux parties, l'une après l'autre.
La première partie est citée dans la
'...'
forme.La deuxième partie est citée dans la
$'...'
forme.La
's/ /\'
partie supprime les guillemets simples, mais passe sinon à sed, telle qu'elle apparaît sur la ligne de commande. C'est-à-dire que la barre oblique inverse n'est pas mangée par bash, elle est transmise à sed.La
$'\n/g'
partie obtient le signe dollar et les guillemets simples enlevés, puis\n
est convertie en un caractère de nouvelle ligne.Tous ensemble, l'argument devient
s / / \ newline/ g
[C'était amusant. Il a fallu du temps pour le déballer. +1 pour une question intéressante.]
la source
L'expression
$'...'
est unbash
-isme qui produit...
avec les séquences d'échappement standard étendues. Th\'
avant cela signifie juste un antislash suivi d' ici la fin de la section citée, la chaîne résultante ests/ /\
. (Oui, vous pouvez basculer entre guillemets au milieu d'une chaîne; cela ne termine pas la chaîne.)La norme POSIX
sed
n’accepte\n
que dans le cadre d’un modèle de recherche. OS X utilise FreeBSDsed
, qui est strictement conforme à POSIX; Comme d’habitude, GNU ajoute des éléments supplémentaires et les utilisateurs de Linux pensent tous qu’il s’agit d’une sorte de «standard» (je serais peut-être plus impressionné si l’un d’eux avait un processus de normalisation).la source
$'...'
partie. Mais ... c'est quois/ /\
? Que veux-tu dire parswitch quoting
?'...'
est un type de coquille citant;$'...'
est un autre. Il y a aussi"..."
et\x
pour citer un seul personnage. Vous pouvez combiner ceux-ci en un seul mot, ce qui correspond à ce qui était fait ici, passant d’une''
chaîne normale à une$''
chaîne pour traduire le\n
. Pour le reste, il construit unesed
commande (s/text/replacement/flags
). Dans ce cas, la commande est démarrée, avec une barre oblique inverse à la fin pour protéger le retour à la ligne littéral ajouté$'\n/g'
. Le résultat est de remplacer tous les/g
espaces (les drapeaux) par des nouvelles lignes.Il est très facile de voir ce qui se passe. Faites simplement écho à la corde!
résulte en
ce qui équivaut à
s/$/\
newline/g
Si vous n'aviez pas le supplément
\
avant lenewline
, le shell interprèteraitnewline
prématurément la fin de la commande.la source