Mon fichier texte ressemble à ceci:
This is one
sentence that is broken.
However this is a good one.
And this
one is
somehow, broken into
many.
Je veux supprimer le caractère de fin de ligne pour toute ligne qui est suivie d'une ligne commençant par une lettre minuscule.
Cela devrait donc être:
This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.
Comment puis-je faire ceci?
Edit: Il y a de très bonnes réponses ici, mais j'ai choisi d'accepter la première qui a fonctionné et qui était la plus ancienne. Merci beaucoup à tous!
Réponses:
essayer
où
$NF !~ /\.$/
faire correspondre la ligne où le dernier élément ne se termine pas par un point,{ printf "%s ",$0
imprimer cette ligne avec un espace de fin et sans saut de ligne,next ; }
récupérer la ligne suivante,{print;}
et l'imprimer.Je suis sûr qu'il y aura une
sed
option.Remarque: cela fonctionnera avec une ligne se terminant par un point, mais la condition dans les phrases commençant par une lettre majuscule ne sera pas fusionnée. Voir la réponse de Stéphane Chazelas.
la source
awk 'ORS=$NF~/\.$/?"\n":" "'
Avec
awk
:Autrement dit, n'ajoutez pas le séparateur d'enregistrement à chaque ligne (ORS vide). Mais ajoutez un séparateur d'enregistrement avant la ligne actuelle si ce n'est pas sur la première ligne et la ligne actuelle ne commence pas par une lettre minuscule. Sinon, ajoutez un espace à la place, sauf sur la première ligne.
la source
And thisone issomehow, broken intomany.
je ne sais pas,awk
mais faut-il joindre des lignes<space>
en plus deRS
? Ou est-ce une erreur utilisateur?En perl:
Techniquement, vous vouliez remplacer "nouvelle ligne suivie d'une lettre minuscule" par "espace et cette lettre minuscule", ce que fait le noyau du script perl ci-dessus:
input
.input
variable pour qu'elle soit le résultat de l'opération de recherche et remplacement.la source
perl -0777 -pe 's/\n([a-z])/ $1/g'
et peut également être fait avec GNU sed assed -zE 's/\n([a-z])/ \1/g'
(en supposant que l'entrée n'a pas de caractères nuls)perl -Mopen=locale -0777 -pe 's/\n(?=[[:lower:]])/ /g'
pour qu'il ne se limite pas aux lettres ASCII.Avec,
sed
vous pouvez utiliser unN;P;D
cycle (afin d'avoir toujours deux lignes dans l'espace de motif et si le premier caractère après la nouvelle ligne est en minuscules, remplacez la nouvelle ligne par un espace) et unt
est - de cette façon, après chaques
substitution, vous redémarrez le cycle:la source
N;P;D
cycle ici, donc je ne reviendrai pas dessus. La différence ici est l't
est - pour vérifier si quelque chose a été remplacé ou non - si le test réussit, nous nous branchons en haut du script, sinon cela signifie que rien n'a été remplacé etP;D
est exécuté. Faites-moi savoir si ce n'est toujours pas clair.Utilisation de
sed
etfmt
:Le script sed insère une nouvelle ligne avant chaque ligne commençant par une majuscule (à l'exception de la toute première ligne de saisie).
sed
La sortie de est ensuite canaliséefmt
pour reformater les paragraphes résultants.Vous pouvez également l'utiliser
par
si vous l'avez installé. C'est un autre reformatage de paragraphe, mais beaucoup plus performant quefmt
, avec beaucoup plus de fonctionnalités et d'options.Notez qu'il y aura une ligne vide entre chaque paragraphe. Les paragraphes doivent être séparés les uns des autres par au moins une ligne vierge. Sans les lignes vides, tout votre échantillon d'entrée est reformaté en un seul paragraphe de plusieurs phrases, par exemple:
Si vous devez supprimer les lignes vides après le reformatage, il vous suffit de les rediriger
sed
- mais cela supprimera TOUTES les lignes vides, y compris celles qui peuvent avoir été dans l'entrée d'origine. par exemplela source
Vous pouvez également le faire:
où:
$\
=>ORS
,$/
=>IRS
=\n
,$"
=space
la source
Python 3
C'est le même regex / substitution que la réponse de Jeff
la source