Remplacer la virgule par une nouvelle ligne dans sed sur MacOS?


287

J'ai un fichier d'identifiants séparés par des virgules. J'essaie de remplacer les virgules par une nouvelle ligne. J'ai essayé:

sed 's/,/\n/g' file

Mais ça ne fonctionne pas. Qu'est-ce que je rate?


12
essayez tr , '\n'. Je suppose que sed traite \ncomme du texte brut.
Prince John Wesley

1
Ça a marché! fichier chat | tr, '\ n'
WildBill

7
tr , '\n' < file- pas de pipe.
Prince John Wesley

À quoi sert la gfin du script? J'obtiens le même comportement sans lui.
HelloGoodbye

Quel shell utilisez-vous? Cela fonctionne pour moi, en utilisant le shell bash.
HelloGoodbye

Réponses:


362

Utilisez trplutôt:

tr , '\n' < file

je cherchais à remplacer "." période, et c'était la solution que je cherche :)
Jonah

1
Il ne fonctionne pas dans le shell bash $ tr, '\ n' aitr utilisation: tr [-Ccsu] string1 string2 tr [-Ccu] -d string1 tr [-Ccu] -s string1 tr [-Ccu] -ds string1 string2
Apprenti

5
Remplacer une virgule par un point-virgule fonctionne également:tr ',' ';' < input.csv > output.csv
Wim Deblauwe

304

Utilisez une chaîne entre guillemets ANSI-C $'string'

Vous avez besoin d'une nouvelle ligne littérale échappée par une barre oblique inversée pour accéder à sed. En bash au moins, les $''chaînes remplaceront \npar une vraie nouvelle ligne, mais ensuite vous devrez doubler la barre oblique inverse que sed verra pour échapper à la nouvelle ligne, par exemple

echo "a,b" | sed -e $'s/,/\\\n/g'

Notez que cela ne fonctionnera pas sur tous les shells , mais fonctionnera sur les plus courants.


5
étrange, cela fonctionne aussi avec une barre oblique inversée de moins c'est à dire echo "a,b" | sed -e $'s/,/\\n/g.
Alexandre Holden Daly le

2
A voté. Pour plus d'informations, consultez la section "CITATION" de man bash.
tboyce12

7
Je l'ai fait fonctionner avec OSX 10.11:, sed -E $'s/<\\/br>/\\\n/g' filepas besoin d'installer gnu-sed
Brice

2
Vérifié travailler sur OS X 10.7 avec l'exemple donné. La -epartie ne semble pas nécessaire.
Yongwei Wu

1
exemple en réponse fonctionne immédiatement pour moi dans OSX 10.11.5
Jurriaan Roelofs

122
sed 's/,/\
/g'

fonctionne sur Mac OS X.


3
Merci pour cela - Je me demandais pourquoi mon vieux truc linux ne fonctionnait pas sous OSX. Mais c'est le cas!
Wyatt8740

6
C'est la seule solution qui fonctionne dans un script sed.
Firstrock

6
Notez que la barre oblique inverse échappe au saut de ligne littéral (de sorte qu'il ne s'agit pas d'un terminateur de commande): ce n'est pas un caractère de continuation de ligne (comme dans bash, etc.). Pour voir la différence, essayez d'écrire la commande ci-dessus sans les guillemets: la barre oblique inverse sera à la place interprétée par le shell comme un caractère de continuation de ligne et la nouvelle ligne sera supprimée. Inversement, incluez le contenu de l'expression citée (sans guillemets) dans un fichier séparé virgule-vers-newline.sed (ce qui élimine la syntaxe du shell), et ça marche!
Nils von Barth

1
c'est bien car il peut remplacer n'importe quoi, pas un personnage. tr semble fonctionner avec uniquement des personnages. si vous mettez une chaîne comme premier paramètre, elle remplacera toute l'occurrence des caractères, pas la chaîne.
Shawn

1
@Droogans Utilisez-vous bash, sh ou un autre shell? Êtes-vous sûr d'utiliser des guillemets simples au lieu de guillemets doubles?
Max Nanasy

22

Si votre utilisation de sed tend à être entièrement des expressions de substitution (comme la mienne a tendance à l'être), vous pouvez également utiliser à la perl -peplace

$ echo 'foo,bar,baz' | perl -pe 's/,/,\n/g'
foo,
bar,
baz

15

Apparemment, \rc'est la clé!

$ sed 's/, /\r/g' file3.txt > file4.txt

Transformé ceci:

ABFS, AIRM, AMED, BOSC, CALI, ECPG, FRGI, GERN, GTIV, HSON, IQNT, JRCC, LTRE,
MACK, MIDD, NKTR, NPSP, PME, PTIX, REFR, RSOL, UBNT, UPI, YONG, ZEUS

Pour ça:

ABFS
AIRM
AMED
BOSC
CALI
ECPG
FRGI
GERN
GTIV
HSON
IQNT
JRCC
LTRE
MACK
MIDD
NKTR
NPSP
PME
PTIX
REFR
RSOL
UBNT
UPI
YONG
ZEUS

Je sais que la question dit OS X, mais cela ne fonctionne pas avec GNU sed-4.2.2-6.fc20.x86_64.
Cristian Ciupitu

10
Gardez à l'esprit que ce \rn'est pas la même chose \n, et cela pourrait interrompre la manipulation et l'utilisation des données.
Joel Purra

3
Désolé, cela n'a pas fonctionné pour moi. Je viens de recevoir un «r» où il devrait y avoir une nouvelle ligne.
Frank de Groot - Schouten

Vous devriez être plus clair dans la réponse que cela donne \r!
pir

Cela a fonctionné pour moi mais je me demande pourquoi! \ n est la norme sur unix stackoverflow.com/questions/1761051/difference-between-n-and-r
Alex

15

Cela fonctionne sur MacOS Mountain Lion (10.8), Solaris 10 (SunOS 5.10) et RHE Linux (Red Hat Enterprise Linux Server version 5.3, Tikanga) ...

$ sed 's/{pattern}/\^J/g' foo.txt > foo2.txt

... où ^Jcela se fait en faisant ctrl+ v+ j. Faites attention \avant ^J.

PS, je sais que le sed dans RHEL est GNU, le sed de MacOS est basé sur FreeBSD, et bien que je ne sois pas sûr du sed de Solaris, je crois que cela fonctionnera à peu près avec n'importe quel sed. YMMV tho '...


12

MacOS est différent, il y a deux façons de résoudre ce problème avec sed dans mac

  • tout d'abord, utilisez \'$'\n''replace \n, cela peut fonctionner sous MacOS:

    sed 's/,/\'$'\n''/g' file
    
  • la seconde, utilisez simplement une ligne vide:

    sed 's/,/\
    /g' file
    
  • Ps. Faites attention à la plage séparée par '

  • le troisième, utilisez gnu-sed pour remplacer le mac-sed


7

Pour le compléter, cela fonctionne aussi:

echo "a,b" | sed "s/,/\\$(echo -e '\n\r')/"

1
Ce serait également approprié pour le concours Obfuscated C, sauf que c'est Bash;)
Aaron R.

@AaronR. Je suis d'accord :-). Je préfère sûrement la trsolution, qui est déjà la réponse acceptée.
ryenus

1
Cela a fonctionné sur OS X. Pourquoi est-ce \n\rau lieu de \r\n? J'ai essayé \r\nquel est l'ordre nécessaire sur Windows. Cependant, après avoir fait cela, il laisse beaucoup de ^Mcaractères de retour chariot vim, donc je pense que c'est censé être seulement \nmais \nseul ne fonctionne pas.
NobleUplift

4

Bien que je sois en retard à ce poste, je mets simplement à jour mes résultats. Cette réponse est uniquement pour Mac OS X.

$ sed 's/new/
> /g' m1.json > m2.json
sed: 1: "s/new/
/g": unescaped newline inside substitute pattern

Dans la commande ci-dessus, j'ai essayé avec Shift + Enter d'ajouter une nouvelle ligne qui ne fonctionnait pas. Donc cette fois, j'ai essayé avec "échapper" la "nouvelle ligne sans échappatoire" comme indiqué par l'erreur.

$ sed 's/new/\
> /g' m1.json > m2.json 

Travaillé! (sous Mac OS X 10.9.3)


Ce n'est pas différent de la réponse de Max Nanasy deux ans avant la vôtre.
miken32

2

Juste pour clarifier: la page de manuel de sed sur OSX (10.8; Darwin Kernel Version 12.4.0) dit:

[...]

Expressions régulières Sed

 The regular expressions used in sed, by default, are basic regular expressions (BREs, see re_format(7) for more information), but extended
 (modern) regular expressions can be used instead if the -E flag is given.  In addition, sed has the following two additions to regular
 expressions:

 1.   In a context address, any character other than a backslash (``\'') or newline character may be used to delimit the regular expression.
      Also, putting a backslash character before the delimiting character causes the character to be treated literally.  For example, in the
      context address \xabc\xdefx, the RE delimiter is an ``x'' and the second ``x'' stands for itself, so that the regular expression is
      ``abcxdef''.

 2.   The escape sequence \n matches a newline character embedded in the pattern space.  You cannot, however, use a literal newline charac-
      ter in an address or in the substitute command.

[...]

donc je suppose qu'il faut utiliser tr - comme mentionné ci-dessus - ou le astucieux

sed "s/,/^M
/g"

note: vous devez taper < ctrl> -v, < return> pour obtenir '^ M' dans l'éditeur vi



1

sedsur macOS Mojave est sorti en 2005, donc une solution consiste à installer le gnu-sed,

brew install gnu-sed

alors l'utilisation gsedfera ce que vous voudrez,

gsed 's/,/\n/g' file

Si vous préférez sed, juste sudo sh -c 'echo /usr/local/opt/gnu-sed/libexec/gnubin > /etc/paths.d/brew'ce qui est suggéré par brew info gnu-sed. Redémarrez votre terme, puis votre sedligne de commande est gsed.


0

FWIW, la ligne suivante fonctionne dans les fenêtres et remplace les points-virgules dans mes variables de chemin par une nouvelle ligne. J'utilise les outils installés sous mon répertoire git bin.

echo %path% | sed -e $'s/;/\\n/g' | less
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.