Conserver les fins de ligne

111

J'ai lancé sed pour faire une substitution sur Windows et j'ai remarqué qu'il convertissait automatiquement les fins de ligne en Unix (\ n). Existe-t-il une option pour dire à sed d'utiliser les fins de ligne Windows (\ r \ n) ou mieux encore de conserver les fins de ligne du fichier?

Remarque: j'utilise sed de unxutils: http://unxutils.sourceforge.net/

Bogdan Calmac
la source
2
Les solutions ci-dessous ne fonctionnent pas sous macOS.
William Entriken
Je suis même arrivé aussi loin et cela n'a toujours pas fonctionnéLC_ALL=C perl -i -e 'binmode $STDIN;undef $/;$_=<>;s|http://911coned.com|https://911coned.com|gm;print' education.html
William Entriken
Donc en fait, la commande ci-dessus fonctionne et je viens de découvrir un bogue dans le git diffprogramme.
William Entriken
1
Vous pouvez utiliser sed (sans aucune option spéciale) + unix2dos
mems

Réponses:

143

Vous pouvez utiliser le -b option de sed pour qu'il traite le fichier comme binaire. Cela résoudra le problème avec le sed de cygwin sous Windows.

Exemple: sed -b 's/foo/bar/'

Si vous souhaitez faire correspondre la fin de la ligne, n'oubliez pas de faire correspondre, capturer et copier le retour chariot facultatif.

Exemple: sed -b 's/foo\(\r\?\)$/bar\1/'

Depuis la page de manuel sed :

-b --binaire

Cette option est disponible sur toutes les plates-formes, mais n'est efficace que lorsque le système d'exploitation fait une distinction entre les fichiers texte et les fichiers binaires. Lorsqu'une telle distinction est faite - comme c'est le cas pour MS-DOS, Windows, Cygwin - les fichiers texte sont composés de lignes séparées par un retour chariot et un caractère de saut de ligne, et sed ne voit pas le CR de fin. Lorsque cette option est spécifiée, sed ouvrira les fichiers d'entrée en mode binaire, ne demandant donc pas ce traitement spécial et considérant que les lignes se terminent par un saut de ligne.

Shlomo
la source
5
Notez que cela ne fonctionne pas avec sed -isur cygwin (pour moi), mais vous pouvez contourner cela. Merci pour la mise à jour - les autres réponses étaient le dernier mot sur ce sujet pendant un certain temps.
harpo
Notez que cette option n'est pas disponible avec sed sur Mac.
Senthil Kumaran
21
Fonctionne pour moi même avec sed -i: il est juste important de savoir comment le taper. Alors que sed -biet sed -i -bfonctionne, sed -ibne fonctionne pas : consultez la page de manuel pour savoir pourquoi (utilise le bcomme suffixe pour la copie de sauvegarde).
Olaf Mandel
2
Utilisation:sed -bi 's/foo/bar/'
Kunal B.
2
Ne fonctionne pas pour moi dans Windows cygwin. Sur les lignes qui ont fait le changement, les fins de ligne sont Unixy. Les autres lignes ont des fins de ligne fenêtrées. Ainsi, mon fichier a un mélange de lignes avec des fins de ligne différentes.
truthadjustr
10

Vous pouvez essayer de sous-marin \npour \r\nà la fin de votre script existant comme ceci:

sed 's/foo/bar/;s/$/\r/'

ou peut-être

 sed -e 's/foo/bar/' -e 's/$/\r/'

Si aucun des deux ci-dessus ne fonctionne, vous devrez consulter la page de manuel spécifique à votre version de sedpour voir si une telle option existe. Notez que les versions * nix de sedne modifient pas les terminateurs de ligne sans qu'on vous le dise.

Une autre alternative consiste à utiliser la cygwinversion seddont ne devrait pas avoir ce comportement indésirable.

SiegeX
la source
15
La version cygwin a ce comportement indésirable.
harpo
2
Si le fichier contient à la fois \ n ( 0x0A) et \ r \ n ( 0x0D 0x0A) - cette solution proposée (de toujours réinjecter le \ r) le casse.
Vlad le
Cela fonctionne pour moi en utilisant MSYS2 / MinGW. Merci @SiegeX.
AntumDeluge
6

Sinon, (la version cygwin de) perl -pene semble pas avoir ce problème.

chercheur
la source
sed sur MacOS n'a pas l'option -b et a des problèmes similaires à ceux décrits dans la question d'origine. L'alternative perl n'a pas ce problème, alors merci pour votre suggestion. sed -i -e 's/<img[^>]*\/>//g' *.xmlremplace les fins de ligne par '\ n' perl -i -p -e 's/<img[^>]*\/>//g' *.xmlpréserve les fins de ligne d'origine
Guruniverse
2

Gnuwin peut être supprimé pour gâcher les nouvelles lignes (win-> unix) si vous spécifiez uniquement le commutateur -b et redirigez. L'utilisation du commutateur -i (en ligne) le gâchera.

Par exemple, sed.exe -b "s / \ xFF \ xFE //" c: \ temp \ in.csv> c: \ temp \ out.csv

Buckley
la source
1
Voir une version avec -imode de travail dans ma réponse .
Vadzim
2

J'ai trouvé que sed-4.4.exede https://github.com/mbuilov/sed-windows est une pure victoire car elle

  • utilise les fins de ligne Windows CRLF en mode par défaut
  • conserve les fins de ligne d'origine en -bmode
  • fonctionne correctement avec le -imode sur place
  • offre également un -zmode avec des \0délimiteurs au lieu de \nqui peut être parfois aussi pratique

Voir aussi la liste des options sed et la liste de tous les ports sed de Windows .

Notez que GnuWin32 sed 4.2.1 ne terminaisons ligne de corruption en -bimode de et n'a pas le -zmode du tout.

Vadzim
la source