J'ai l'habitude d'écrire une ligne par phrase parce que je compile généralement des choses à la latex, ou je vous écris dans un autre format où les pauses de la ligne sont ignorées. J'utilise une ligne vide pour indiquer le début d'un nouveau paragraphe.
Maintenant, j'ai un fichier écrit dans ce style que je voudrais juste envoyer en tant que texte brut. Je veux éliminer tous les gilles simples, mais laisser les doubles gelles intacts. C'est ce que j'ai fait:
sed 's/$^/NEWLINE/' file.txt | awk '{printf "%s ",$0}' | sed 's/NEWLINE/\n\n/g' > linebreakfile.txt
Ceci remplace les lignes vides avec un texte que je suis confiant n'apparaît pas dans le fichier: NEWLINE
_ Et puis il se débarrasse de toutes les pauses de ligne avec AWK (j'ai trouvé cette astuce sur un site Web), puis il remplace la NEWLINE
s avec les deux chevichets requis.
Cela ressemble à une longue façon de faire une chose assez simple. Y a-t-il un moyen plus simple? En outre, s'il y avait un moyen de remplacer plusieurs espaces (qui se glissent parfois pour une raison quelconque) avec des espaces simples, ce serait bien aussi.
J'utilise Emacs, donc s'il y a des trucs spécifiques d'Emacs, c'est bien, mais je préfère voir une version pure SED ou Pure Awk.
Vous pouvez utiliser awk comme ceci:
$ awk ' /^$/ { print; } /./ { printf("%s ", $0); } ' test
Ou si vous avez besoin d'une nouvelle ligne supplémentaire à la fin:
$ awk ' /^$/ { print; } /./ { printf("%s ", $0); } END { print ""; } ' test
Ou si vous souhaitez séparer les paragraphes par une nouvelle ligne:
$ awk ' /^$/ { print "\n"; } /./ { printf("%s ", $0); } END { print ""; } ' test
Ces commandes AWK utilisent des actions qui sont gardées par des modèles:
/regex/
ou
END
Une action suivante n'est exécutée que si le motif correspond à la ligne en cours.
Et le ^$.
Les personnages ont une signification particulière dans des expressions régulières, où ^
correspond au début de la ligne, $
la fin et .
un caractère arbitraire.
Utilisez AWK ou PERL mode de paragraphe pour traiter un paragraphe de fichier par paragraphe, où les paragraphes sont séparés par des lignes vierges.
awk -vRS= '
NR!=1 {print ""} # print blank line before every record but the first
{ # do this for every record (i.e. paragraph):
gsub(" *\n *"," "); # replace newlines by spaces, compressing spaces
sub(" *$",""); # remove spaces at the end of the paragraph
print
}
'
Perl -000 -pe ' # for every paragraph:
print "\n" unless $.==1; # print a blank line, except before the first paragraph
s/ *\n *(?!$)/ /g; # replace newlines by spaces, compressing spaces, but not at the end of the paragraph
s/ *\n+\z/\n/ # normalize the last line end of the paragraph
'
Bien sûr, étant donné que cela n'analyse pas le (LA) Tex, il sera horriblement mutilé des commentaires, des environnements verbatim et une autre syntaxe spéciale. Vous voudrez peut-être examiner Detex ou d'autres convertisseurs Tex-to-Text.
$ sed -e ':a;N;$!ba;s/\(.\)\n/\1 /g' -e 's/\n/\n\n/' test.text
Notez que dans cette solution :a
Création d'une étiquette et n'utilise pas la commande a
.
Utilisez tr
: $ tr -s ' ' <test.text
Si j'ai bien compris, une ligne vide implique deux nouvelles lignes consécutives, \n\n
.
Si tel est le cas, une solution possible consisterait à éliminer toutes les occurrences singulières des nouvelles lignes.
À Perl, une affirmation de lunette est une solution pour y parvenir:
$ Perl -0777 -i -pe 's/\n(?=[^\n])//g' test
-0777
le drapeau est effectivement slurps le fichier entier dans une seule chaîne-p
indique à Perl d'imprimer la chaîne qu'il fonctionne par défaut-i
Spécifie l'édition de lieu(faire revivre une question antique)
Cela semble être exactement ce que fmt
et par
sont à reformatage de paragraphes. Comme vous (et aussi comme de nombreux programmes), ils définissent les limites de paragraphe comme une (ou plusieurs) lignes vides. Essayez de tuyer votre texte à travers l'un d'entre eux.
fmt
est un utilitaire UNIX standard et peut être trouvé dans GNU Coreutils.
par
est une très améliorée fmt
écrite par Adam M. Costello, qui peut être trouvée à http://www.nicemice.net/par/ (il a Aussi été emballé pour plusieurs distributions, y compris Debian, je l'ai emballé pour Debian en janvier 1996, bien qu'il y ait un nouveau responsable de la PKG maintenant.).
Après avoir vu des exemples de Perl et Awk Compact, j'étais réticent à poster cela, mais j'avais déjà passé l'exercice, et c'est un script fonctionnel, raisonnablement documenté; Ce seul point peut-il intéresser certains .. (sed avec des commentaires! :)
Ce script considère que les lignes vides soient vides, même si elles contiennent des espaces.
Plusieurs espaces dans le texte sont condensés à un seul espace.
Espace de fuite est supprimé des lignes de texte. Les lignes vides consécutives sont effondrées à une seule ligne. Le script laisse des lignes vierges supérieures et inférieures intactes.
Pour quelque chose de plus que les scripts les plus triviaux, SED peut être écrit beaucoup plus facilement sur une forme structurée, en tant que fichier de script distinct. Voici un exemple exemple.
en utilisant la syntaxe de regex étendue
[.____] appeler: $ sed -rf script texte-fichier
:first-empty-line
#================
/^[[:space:]]*$/ { # if pattern-space is empty...
$q # last line # flush-quit
n # pattern-flush=nextline-continue
:subsequent-empty-line
#=====================
/^[[:space:]]*$/ { # if pattern-space is empty...
$d # last line # pattern-delete-cycle
N # pattern+=nl+nextline
s/.*\n// # scrap the leading 'blank' line
t subsequent-empty-line # branch-on-substitute
}
}
:text-line
#=========
$q # last line # flush-quit
s/^(.*)[[:space:]]*/\1/ # trim trailing whitespace
s/ +/ /g # condense mulltiple spaces
N # pattern+=nl+nextline
/^.*\n[[:space:]]*$/ { # if newly-read line is blank
P # pattern-first-line-print
s/^.*\n// # remove the leading 'text' line
t first-empty-line # branch-on-substitute
}
# read line is text
s/\n/ / # replace \n with a space
t text-line # branch-on-substitute
Remarque: flush
, dans les commentaires, moyens: Envoyez l'espace de motif à la gestion interne de STDOUT interne de SED. Cela ne signifie pas une impression définitive à stdout. La sortie dépend de l'-n
option. par exemple. Les moyens de commande q
rincer et quitter ... Comparez ces deux extraits: echo x |sed -e q
imprime x, echo x |sed -ne q
Imprime rien, alors que l'utilisation de la commande p
imprimerait deux fois ou une fois, en fonction de la -n
option.
Dans Emacs, j'utilise parfois ce regex
:
^J\([^^J]\) -> \1
Veux dire:
remplacez chaque nouvelle ligne qui est suivie de quelque chose qui n'est pas une nouvelle ligne avec seulement la chose, qui a suivi la nouvelle ligne de cette façon de vous débarrasser de toutes les nouvelles lignes dans un paragraphe, mais gardez les paragraphes (double-litline)
Il s'avère que avec auto-fill-mode
ON, EMACS fait un très bon travail pour mes cas d'utilisation simples avec juste M-q
...