Question Comment puis-je remplacer une nouvelle ligne (\ n) en utilisant sed?


Comment puis-je remplacer une nouvelle ligne (\n) utilisant la commande sed?

J'ai essayé sans succès:

sed 's#\n# #g' file
sed 's#^$# #g' file

Comment je le répare?


1125
2017-08-09 19:10


origine


Réponses:


Utilisez cette solution avec GNU sed:

sed ':a;N;$!ba;s/\n/ /g' file

Cela va lire le fichier entier dans une boucle, puis remplace la nouvelle ligne (s) avec un espace.

Explication:

  1. Créer une étiquette via :a.
  2. Ajoutez la ligne actuelle et la ligne suivante à l'espace de motif via N.
  3. Si nous sommes avant la dernière ligne, branchez à l'étiquette créée $!ba ($! signifie ne pas le faire sur la dernière ligne car il devrait y avoir un retour à la ligne final).
  4. Enfin, la substitution remplace chaque nouvelle ligne avec un espace sur l'espace de modèle (qui est le fichier entier).

Voici une syntaxe compatible multi plates-formes qui fonctionne avec BSD et OS X sed (selon Commentaire @Benjie):

sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file

1278
2017-08-09 20:26



Utilisation tr au lieu?

tr '\n' ' ' < input_filename

ou supprimez entièrement les caractères de nouvelle ligne:

tr -d '\n' < input.txt > output.txt

ou si vous avez la version GNU (avec ses longues options)

tr --delete '\n' < input.txt > output.txt

1447
2017-08-09 19:16



Réponse rapide:

sed ':a;N;$!ba;s/\n/ /g' file
  1. :une  créer une étiquette "a"
  2. N  ajouter la ligne suivante à l'espace de motif
  3. $!  sinon la dernière ligne, ba  branche (aller à) étiqueter 'a'
  4. s  remplacer, / \ n /  regex pour nouvelle ligne, / /  par un espace, /g  match global (autant de fois que possible)

sed passera en boucle à travers les étapes 1 à 3 jusqu'à ce qu'il atteigne la dernière ligne, obtenant toutes les lignes dans l'espace du modèle où sed va remplacer tous les caractères \ n


Alternatives:

Toutes les alternatives, contrairement sed n'aura pas besoin d'atteindre la dernière ligne pour commencer le processus

avec frapper, lent

while read line; do printf "%s" "$line "; done < file

avec Perl, sed-comme la vitesse

perl -p -e 's/\n/ /' file

avec tr, plus rapide que sed, peut remplacer par un seul caractère

tr '\n' ' ' < file

avec coller, tr-comme la vitesse, peut remplacer par un seul caractère

paste -s -d ' ' file

avec awk, tr-comme la vitesse

awk 1 ORS=' ' file

Autre alternative comme "echo $ (<fichier)" est lent, ne fonctionne que sur de petits fichiers et doit traiter tout le fichier pour commencer le processus.


Longue réponse du sed FAQ 5.10:

5.10. Pourquoi ne puis-je pas faire correspondre ou supprimer un saut de ligne à l'aide de l'échappement \ n
      séquence? Pourquoi ne puis-je pas associer 2 lignes ou plus en utilisant \ n?

Le \ n ne correspondra jamais au retour à la ligne à la fin de la ligne car le
   newline est toujours enlevé avant que la ligne ne soit placée dans le
   espace de motif. Pour obtenir 2 lignes ou plus dans l'espace de motif, utilisez
   la commande 'N' ou quelque chose de similaire (comme 'H; ...; g;').

Sed fonctionne comme ceci: sed lit une ligne à la fois, coupe la
   terminer le saut de ligne, place ce qui reste dans l'espace
   le script sed peut l'adresser ou le changer, et quand l'espace de pattern
   est imprimé, ajoute une nouvelle ligne à stdout (ou à un fichier). Si la
   espace de motif est entièrement ou partiellement supprimé avec 'd' ou 'D', le
newline est ne pas ajouté dans de tels cas. Ainsi, des scripts comme

  sed 's/\n//' file       # to delete newlines from each line             
  sed 's/\n/foo\n/' file  # to add a word to the end of each line         

ne fonctionnera JAMAIS, car la nouvelle ligne de fin est supprimée avant
   la ligne est placée dans l'espace des motifs. Pour effectuer les tâches ci-dessus,
   utilisez l'un de ces scripts à la place:

  tr -d '\n' < file              # use tr to delete newlines              
  sed ':a;N;$!ba;s/\n//g' file   # GNU sed to delete newlines             
  sed 's/$/ foo/' file           # add "foo" to end of each line          

Depuis les versions de sed autres que GNU sed ont des limites à la taille de
   le buffer de pattern, l'utilitaire Unix 'tr' est à privilégier ici.
   Si la dernière ligne du fichier contient une nouvelle ligne, GNU sed ajoutera
   cette nouvelle ligne à la sortie, mais supprimer tous les autres, alors que tr sera
   supprimer toutes les nouvelles lignes.

Pour faire correspondre un bloc de deux lignes ou plus, il y a trois choix de base:
   (1) utilisez la commande 'N' pour ajouter la ligne Next à l'espace du pattern;
   (2) utiliser la commande 'H' au moins deux fois pour ajouter la ligne courante
   à l'espace de maintien, puis récupérer les lignes de l'espace de maintien
   avec x, g ou G; ou (3) utiliser des plages d'adresses (voir la section 3.3 ci-dessus)
   pour faire correspondre les lignes entre deux adresses spécifiées.

Les choix (1) et (2) mettront un \ n dans l'espace de pattern, où
   peut être adressé comme souhaité ('s / ABC \ nXYZ / alphabet / g'). Un exemple
   d'utiliser 'N' pour supprimer un bloc de lignes apparaît dans la section 4.13
   ("Comment supprimer un bloc de spécifique lignes consécutives? ").
   exemple peut être modifié en changeant la commande de suppression à quelque chose
   d'autre, comme 'p' (print), 'i' (insérer), 'c' (changer), 'a' (ajouter),
   ou 's' (substitut).

Choice (3) ne mettra pas un \ n dans l'espace de pattern, mais il Est-ce que
   correspondre à un bloc de lignes consécutives, il se peut donc que vous ne le faites pas
   besoin même de \ n pour trouver ce que vous cherchez. Depuis GNU sed
   la version 3.02.80 supporte maintenant cette syntaxe:

  sed '/start/,+4d'  # to delete "start" plus the next 4 lines,           

en plus de la gamme traditionnelle '/ from here /, / to there / {...}'
   adresses, il peut être possible d'éviter l'utilisation de \ n entièrement.


412
2017-10-08 14:55



Une alternative awk plus courte:

awk 1 ORS=' '

Explication

Un programme awk est constitué de règles composées de blocs de code conditionnels, à savoir:

condition { code-block }

Si le bloc de code est omis, la valeur par défaut est utilisée: { print $0 }. Ainsi, le 1 est interprété comme une véritable condition et print $0 est exécuté pour chaque ligne.

Quand awk lit l'entrée, il le divise en enregistrements en fonction de la valeur de RS (Record Separator), qui est par défaut une nouvelle ligne, donc awk analysera par défaut l'entrée par ligne. Le fractionnement consiste également à se déshabiller RS à partir de l'enregistrement d'entrée.

Maintenant, lors de l'impression d'un disque, ORS (Output Record Separator) y est ajouté (par défaut, il s'agit d'une nouvelle ligne). Donc en changeant ORSdans un espace, toutes les nouvelles lignes sont changées en espaces.


175
2018-02-13 12:12



gnu sed a une option -z pour les enregistrements séparés par zéro (lignes). Vous pouvez simplement appeler:

sed -z 's/\n/ /g'

91
2018-05-05 09:43



le Perl la version fonctionne comme vous l'attendiez.

perl -i -p -e 's/\n//' file

Comme indiqué dans les commentaires, il vaut la peine de noter que cette modification est en place. -i.bak vous donnera une sauvegarde du fichier original avant le remplacement au cas où votre expression régulière n'est pas aussi intelligent que vous le pensiez.


75
2017-08-09 19:25



Qui a besoin sed? Voici la bash façon:

cat test.txt |  while read line; do echo -n "$line "; done

40
2017-08-11 12:07



Afin de remplacer toutes les nouvelles lignes avec des espaces en utilisant awk, sans lire le fichier entier en mémoire:

awk '{printf "%s ", $0}' inputfile

Si vous voulez un retour à la ligne final:

awk '{printf "%s ", $0} END {printf "\n"}' inputfile

Vous pouvez utiliser un caractère autre que l'espace:

awk '{printf "%s|", $0} END {printf "\n"}' inputfile

23
2018-03-30 06:41



Trois choses.

  1. tr (ou cat, etc.) n'est absolument pas nécessaire. (GNOU) sed et (GNU) awk, lorsqu'il est combiné, peut faire 99,9% de tout traitement de texte dont vous avez besoin.

  2. stream! = basé sur la ligne. ed est un éditeur basé sur une ligne. sed n'est pas. Voir sed conférence pour plus d'informations sur la différence. La plupart des gens confondent sed car elle est, par défaut, peu gourmande dans sa recherche de correspondances SIMPLE - par exemple, lors de la recherche de motifs et du remplacement par un ou deux caractères, elle ne se substitue par défaut qu'à la première occurrence trouvée ( sauf indication contraire par la commande globale). Il n'y aurait même pas de commande globale si elle était basée sur une ligne plutôt que sur STREAM, car elle n'évaluerait que les lignes à la fois. Essayez de courir ed; vous remarquerez la différence. ed est très utile si vous voulez parcourir des lignes spécifiques (comme dans une boucle for), mais la plupart du temps, vous voulez juste sed.

  3. Cela étant dit,

    sed -e '{:q;N;s/\n/ /g;t q}' file
    

    fonctionne très bien dans GNU sed version 4.2.1. La commande ci-dessus remplacera toutes les nouvelles lignes par des espaces. C'est moche et un peu lourd à taper, mais ça marche très bien. le {}de peuvent être laissés de côté, car ils ne sont inclus que pour des raisons de santé mentale.


20
2018-05-01 11:04