Comment remplacer un saut de ligne (" \n
") avec un espace (" ") en utilisant le sed
commande ?
J'ai essayé sans succès :
sed 's#\n# #g' file
sed 's#^$# #g' file
Comment puis-je le réparer ?
Comment remplacer un saut de ligne (" \n
") avec un espace (" ") en utilisant le sed
commande ?
J'ai essayé sans succès :
sed 's#\n# #g' file
sed 's#^$# #g' file
Comment puis-je le réparer ?
sed
est destiné à être utilisé sur une entrée de type ligne. Bien qu'il puisse faire ce dont vous avez besoin.
Une meilleure option ici est d'utiliser l'option tr
comme suit :
tr '\n' ' ' < input_filename
ou supprimer 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
Je ne comprends pas pourquoi sed ne peut pas le faire. S'il vous plaît, clarifiez pour utiliser un autre outil.
Sed est basé sur les lignes, il est donc difficile pour lui de saisir les nouvelles lignes.
Alexander : Est-ce que "stream editor" signifie "basé sur la ligne" ? Peut-être que le nom prête à confusion.
Utilisez cette solution avec GNU sed
:
sed ':a;N;$!ba;s/\n/ /g' file
Cette méthode lit le fichier entier en boucle, puis remplace les nouvelles lignes par des espaces.
Explication :
:a
.N
.$!ba
( $!
signifie qu'il ne faut pas le faire sur la dernière ligne car il doit y avoir un dernier saut de ligne).Voici une syntaxe compatible avec les plateformes, qui fonctionne avec BSD et OS X. sed
(selon Commentaire de @Benjie ) :
sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file
Comme vous pouvez le constater, l'utilisation de sed
pour ce problème autrement simple est problématique. Pour une solution plus simple et adéquate, voir cette réponse .
Vous pouvez l'exécuter sur plusieurs plates-formes (c'est-à-dire sur Mac OS X) en exécutant séparément les commandes plutôt que de les séparer par des points-virgules : sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g'
Voir le numéro 3 ci-dessus. Il semble que $ ! signifie qu'il ne faut pas le faire sur la dernière ligne car il devrait y avoir un dernier saut de ligne.
sed ':a;N;$!ba;s/\n/ /g' file
sed passera en boucle les étapes 1 à 3 jusqu'à ce qu'il atteigne la dernière ligne, en obtenant que toutes les lignes s'insèrent dans l'espace du motif où sed substituera toutes les lignes \n caractères
Toutes les alternatives, contrairement sed n'auront pas besoin d'atteindre la dernière ligne pour commencer le processus
con bash , lent
while read line; do printf "%s" "$line "; done < file
con perl , sed -une vitesse similaire
perl -p -e 's/\n/ /' file
con tr plus rapide que sed peut être remplacé par un seul caractère
tr '\n' ' ' < file
con pâte , tr -comme la vitesse, peut être remplacé par un seul personnage
paste -s -d ' ' file
con awk , tr -une vitesse similaire
awk 1 ORS=' ' file
D'autres alternatives comme "echo $(<fichier)" est lent, ne fonctionne que sur les petits fichiers et doit traiter le fichier entier pour commencer le processus.
5.10. Pourquoi ne puis-je pas faire correspondre ou supprimer une nouvelle ligne en utilisant la fonction \n s'échapper
séquence ? Pourquoi je ne peux pas faire correspondre 2 lignes ou plus en utilisant \n ?
El \n ne correspondra jamais au saut de ligne en fin de ligne, car la fonction
la nouvelle ligne est toujours supprimée avant que la ligne ne soit placée dans le dossier de l'utilisateur.
espace pour les motifs. Pour placer 2 lignes ou plus dans l'espace du motif, utilisez
la commande 'N' ou quelque chose de similaire (comme 'H ;...;g;').
Sed fonctionne de la manière suivante : sed lit une ligne à la fois, coupe le
le saut de ligne de fin, met ce qui reste dans l'espace du motif où
le sed script peut l'aborder ou le modifier, et lorsque l'espace de motif
est imprimée, ajoute un saut de ligne à stdout (ou à un fichier). Si le
l'espace du motif est entièrement ou partiellement supprimé avec "d" ou "D", l'élément
la nouvelle ligne est no ajoutés 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. antes de
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
Étant donné que les versions de sed autres que GNU sed ont des limites à la taille des fichiers
le tampon de motifs, l'utilitaire Unix 'tr' est à préférer ici.
Si la dernière ligne du fichier contient un saut de ligne, GNU sed ajoutera
cette nouvelle ligne à la sortie mais supprime toutes les autres, alors que tr va
supprimer tous les retours à la ligne.
Pour faire correspondre un bloc de deux lignes ou plus, il existe trois choix de base :
(1) utilisez la commande 'N' pour ajouter la ligne suivante à l'espace du motif ;
(2) utilisez la commande 'H' au moins deux fois pour ajouter la ligne en cours.
à l'espace Hold, puis récupérer les lignes de l'espace Hold
avec x, g, ou G ; ou (3) utiliser des plages d'adresses (voir section 3.3, ci-dessus)
pour faire correspondre les lignes entre deux adresses spécifiées.
Les choix (1) et (2) mettront une \n dans l'espace du modèle, où il
peuvent être adressés comme on le souhaite ('s/ABC \nXYZ /alphabet/g'). Un exemple
l'utilisation de 'N' pour supprimer un bloc de lignes apparaît dans la section 4.13.
("Comment supprimer un bloc de spécifique lignes consécutives ?"). Ce site
L'exemple peut être modifié en remplaçant la commande de suppression par quelque chose comme
autre, comme 'p' (imprimer), 'i' (insérer), 'c' (changer), 'a' (ajouter),
ou "s" (substitut).
Le choix (3) ne mettra pas un \n dans l'espace du modèle, mais il hace
correspondre à un bloc de lignes consécutives, il se peut donc que vous ne
même besoin de la \n pour trouver ce que vous cherchez. Depuis que GNU sed
La version 3.02.80 prend désormais en charge cette syntaxe :
sed '/start/,+4d' # to delete "start" plus the next 4 lines,
en plus de la gamme traditionnelle "/d'ici/,/de là/{...}".
il peut être possible d'éviter l'utilisation de \n entièrement.
Merci pour la commande coller. Je ne la connaissais pas. J'ai un fichier contenant des URL et je voulais les ouvrir toutes en même temps dans le navigateur Chrome. C'est ce que j'ai fait (sur Mac OS X) : paste -s -d ' ' url.txt | xargs open
Il fonctionne très bien.
Bonne réponse. Il y a un léger problème dans l'alternative bash. Elle échoue sur les lignes qui sont interprétées comme des interrupteurs pour echo. C'est pourquoi je n'utilise jamais echo pour imprimer des données variables. Utilisez printf '%s' "$line "
à la place.
Une alternative awk plus courte :
awk 1 ORS=' '
Un programme awk est construit à partir de règles qui consistent en des blocs de code conditionnels, c'est-à-dire.. :
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 condition vraie et print $0
est exécuté pour chaque ligne.
Lorsque awk
lit l'entrée, il la divise en enregistrements basés sur la valeur de RS
(séparateur d'enregistrement), qui est par défaut une nouvelle ligne, donc awk
analysera par défaut l'entrée par ligne. Le découpage implique également de supprimer RS
de l'enregistrement d'entrée.
Maintenant, lors de l'impression d'un enregistrement, ORS
(Output Record Separator) lui est ajouté, par défaut c'est encore une nouvelle ligne. Ainsi, en modifiant ORS
en espace, tous les retours à la ligne sont transformés en espaces.
Si cela a plus de sens, cela pourrait effectivement être écrit comme suit : awk 'BEGIN { ORS=" " } { print $0 } END { print "\n"} ' file.txt
(en ajoutant un saut de ligne final juste pour illustrer le début/la fin) ; le "1" est évalué à true
(traiter la ligne) et print
(imprimer la ligne). On peut également ajouter une condition à cette expression, par exemple, ne travailler que sur les lignes correspondant à un motif : awk 'BEGIN { ORS=" " } /pattern/ { print $0 } END { print "\n"} '
El Perl fonctionne comme vous l'aviez prévu.
perl -i -p -e 's/\n//' file
Comme indiqué dans les commentaires, il convient 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 tu le pensais.
Veuillez au moins mentionner que -i
sans suffixe fait aucune sauvegarde . -i.bak
vous protège d'une erreur facile et laide (par exemple, oublier de taper -p
et la mise à zéro du fichier).
@Telemachus : C'est un point juste, mais on peut l'argumenter dans les deux sens. La principale raison pour laquelle je ne l'ai pas mentionné est que l'exemple sed dans la question de l'OP ne fait pas de sauvegardes, donc cela semble superflu ici. L'autre raison est que je n'ai jamais vraiment utilisé la fonctionnalité de sauvegarde (je trouve les sauvegardes automatiques ennuyeuses, en fait), donc j'oublie toujours qu'elle est là. La troisième raison est que cela rallonge ma ligne de commande de quatre caractères. Pour le meilleur ou pour le pire (probablement pour le pire), je suis un minimaliste compulsif ; je préfère simplement la brièveté. Je sais que vous n'êtes pas d'accord. Je ferai de mon mieux pour ne pas oublier d'avertir des sauvegardes à l'avenir.
@Ire_and_curses : En fait, tu viens de donner un très bon argument pour m'ignorer. C'est-à-dire que vous avez des raisons pour vos choix, et que je sois d'accord ou non avec ces choix, je respecte cela. Je ne sais pas exactement pourquoi, mais j'ai été sur une larme à propos de cette chose en particulier récemment (le -i
en Perl sans suffixe). Je suis sûr que je trouverai bien assez tôt un autre sujet d'obsession :)
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
38 votes
tr
n'est le bon outil pour le travail que si l'on remplace un caractère unique par un caractère unique, alors que l'exemple ci-dessus montre remplacer newline par un espace . Donc, dans l'exemple ci-dessus, tr pourrait fonctionner Mais serait limitatif par la suite.0 votes
@Mayhem,
sed 's/$/ NewDelim/' | tr '\n' ' '
. Utilisezsed
pour ajouter le nouveau délimiteur à la fin de chaque ligne, puis supprimer les retours à la ligne avec la commandetr
. Moins énigmatique que lesed
la seule façon, IMO.13 votes
tr
dans le bon outil pour le travail parce que le questionneur voulait remplacer chaque nouvelle ligne par un espace, comme indiqué dans son exemple. Le remplacement des retours à la ligne n'est qu'une bizarrerie poursed
mais facilement réalisable partr
. Il s'agit d'une question courante. L'exécution de remplacements d'expressions rationnelles n'est pas effectuée partr
mais parsed
qui serait le bon outil... pour une autre question.3 votes
"tr" peut aussi juste effacer la nouvelle ligne ` tr -d ' \n ' ` mais vous pouvez aussi supprimer les retours pour être plus universel ` tr -d ' \012\015 ' `.
3 votes
ATTENTION : "tr" agit différemment en ce qui concerne les plages de caractères entre Linux et les anciennes machines Solaris (EG sol5.8). EG : ` tr -d 'a-z' ` et ` tr -d '[a-z]' `. Pour cela, je vous recommande d'utiliser "sed" qui n'a pas cette différence.
2 votes
@MikeS Merci pour la réponse. Suivez
tr '\012' ' '
avec unecho
. Sinon, le dernier saut de ligne du fichier est également supprimé.tr '\012' ' ' < filename; echo
fait l'affaire.1 votes
@BernieReiter Il est possible d'atténuer le problème de la suppression du dernier saut de ligne en appelant la fonction
tr
dans unecho
sous-shell de commande :echo $(tr "\012" " ")
.0 votes
@Patrick Dark
cat text.txt | echo $(tr "\012" " ")
Cool :-) Merci pour le conseil !0 votes
tr
n'est pas utile si vous voulez remplacer certaines nouvelles lignes, selon qu'elles ont d'autres caractères à côté ou non. Voici une bonnesed
réponse plus simple que toutes celles énumérées ci-dessous : stackoverflow.com/a/12129896/1340440 votes
@MikeS Il s'agit juste d'un exemple de jouet, et l'auteur de la question a spécifiquement demandé comment le faire avec
sed
0 votes
perl -0777 -p -e 's/\n/ /' file