Comment mettre des phrases sur des lignes séparées sur Linux

J'ai un devoir de mettre des phrases dans un file text sur des lignes séparées. Quelque chose comme ça marche presque:

cat file.txt | tr '.' '\n' 

Mais je ne veux pas perdre des points, des points d'interrogation et des points d'exclamation de mes phrases. Comment puis-je faire ce travail?

Je ne peux pas être sûr sans voir un exemple réel de vos données, mais ce que vous searchz probablement est l'ajout d'une nouvelle ligne après chaque occurrence de . , ! et ? . Je ne sais pas comment vous voulez traiter les points-virgules ( ; ) car ils ne marquent pas vraiment la fin d'une phrase. C'est à toi de voir.

Quoi qu'il en soit, vous pourriez essayer sed :

 $ echo 'This is a sentence! And so is this. And this one?' | sed 's/[.!?] */&\n/g' This is a sentence! And so is this. And this one? 

Le s/// est l'opérateur de substitution. Son format général est s/pat/replacement et il replacea pat avec le replacement . Le g à la fin fait courir le rlocation sur toutes les occurrences de pat . Sans cela, il s'arrêterait au premier. Le & est une construction spéciale sed qui signifie "tout ce qui a été apparié". Donc, ici, nous remplaçons n'importe lequel de . , ! , ou ? avec tout ce qui a été jumelé et une nouvelle ligne.

Si votre text peut inclure des abréviations telles que, eg , vous pouvez replace seulement si la lettre suivante est un CAPITAL:

 $ echo 'This is a sentence! And so is this. And this one? Negative, ie no.' | sed 's/\([.!?]\) \([[:upper:]]\)/\1\n\2/g' This is a sentence! And so is this. And this one? Negative, ie no. 

Notez que cela ne va pas traiter avec des phrases comme le Dr. Jones said hello. correctement car il supposera que le . après Dr définit une phrase étant donné que la prochaine lettre est en majuscule. Cependant, nous approchons maintenant d'un niveau de complexité qui va bien au-delà du simple format Q & A et nécessite en fait un parsingur de langage naturel complet.

Essayer:

 sed -e :1 -e 's/\([.?!]\)[[:blank:]]\{1,\}\([^[:blank:]]\)/\1\ \2/;t1' 

Sur une input comme:

 Sentence 1. Sentence 1.2? Sentence 2!? Sentence 3. Sentence 4... Sentence 5. 

Il donne:

 Sentence 1. Sentence 1.2? Sentence 2!? Sentence 3. Sentence 4... Sentence 5. 

(et est POSIX).

Si votre text comporte plus d'une ligne, les phrases peuvent s'étendre sur plusieurs lignes. Avec sed je replaceais d'abord les lignes par l'espace (sauf le dernier saut), puis presser les espaces et replace chaque espace après l'un des [.!?] une nouvelle ligne:

 sed ':a;$!N;s/\n/ /g;ta s/\( \)*/\1/g s/\([.!?]\) /\1\ /g' infile 

donc pour cette input d'échantillon:

 A single '-' operand is not really an option ! It stands for standard input. Or for standard output ? For example: 'smth -' reads from stdin; and is equal to plain 'smth'... Could it appear as any operand that requires a file name ? Certainly ! 

la sortie est:

 A single '-' operand is not really an option ! It stands for standard input. Or for standard output ? For example: 'smth -' reads from stdin; and is equal to plain 'smth'... Could it appear as any operand that requires a file name ? Certainly ! 

Utilisez sed place:

 sed 's/\./\.\n/' file.txt 

La tâche comporte quelques pièges. Une option pourrait être:

 sed 's/\([.?!;]\) */\1\n/g' file.txt 

Ceci substitue les caractères du jeu de caractères donné ( [.?!;] , Ajoute un point-virgule ou supprime le point-virgule selon vos besoins) suivi des espaces vides optionnels ( * ) par le caractère remplacé ( \( et \) ) et une nouvelle ligne ( \n ).

Essayer:

 awk -F. '{ for (i=1;i<=NF;i++) printf "%s.\n",$i ;} ' < input_file > output_file 

  • awk utilise . (point) comme séparateur,
  • et boucle pour chaque champ, imprimant la ligne, un point une nouvelle ligne

Il y a de la vie en dehors d'une seule ligne …

Les séparateurs de phrases ne sont jamais prêts, il y a toujours un détail à corriger: un Multiliner Perl!

 #!/usr/bin/perl use ssortingct; my $pont=qr{[.!?]+}; ## pontuation my $abrev=qr{\b(?:Pr|Dr|Mr|[AZ])\.}; ## abreviations $/=""; while(<>){ chomp; ## for each paragraph, s/\h*\n\h*/ /g; ## remove \n s/($pont)\h+(\S)/$1\n$2/g; ## pontuation+space s/($abrev)\n/$1 /g; ## undo \n after abreviations print "$_\n\n"; } 

donc avec:

 A single '-' operand is not really an option ! It stands for standard input. Or for standard output ? For example: 'smth -' reads from stdin; and is equal to plain 'smth'... Could it appear as any operand that requires a file name ? Certainly ! Robert L. Stevenson wrote Dr. Jekyll and Mr. Hyde. Back in 12.12.1886 the end 

la sortie est:

 A single '-' operand is not really an option ! It stands for standard input. Or for standard output ? For example: 'smth -' reads from stdin; and is equal to plain 'smth'... Could it appear as any operand that requires a file name ? Certainly ! Robert L. Stevenson wrote Dr. Jekyll and Mr. Hyde. Back in 12.12.1886 the end 
 sed 's/\([.!?] *\)\{0,1\}/\1\\/g' <infile | xargs printf %s\\n 

J'ai eu cette chose w / fold avant – ce qui était rapide – mais j'ai réalisé que je pourrais faire la même chose avec xargs sans prétraitement d'input ou d'implémenter des loops de twig sed si je juste backslash-échappé tout ce qui n'était pas un le caractère de fin ou d'autres espaces suivants.

Ainsi, dans l'instruction ci-dessus, sed correspondra soit à la string nulle, soit à une séquence de terminaison pour chaque caractère (pas dans la séquence) qui se produit en input. Dans le membre de droite, sed substitue la string nulle ou la séquence de terminaison dans \1 et insère ensuite une barre oblique inverse. Le résultat est que tous les caractères sauf un .!? quand il est suivi d'au less un espace, il obtient \ backslash-échapped. Cela inclut le \n ewline que sed insère après chaque substitution quand il écrit dans stdout.

Parce que xargs supprimera entièrement une barre oblique inverse et splita les args, il transmettra son utilitaire nommé sur les espaces non échappés, printf printing de toutes les strings semblables à des phrases que xargs lit en input sans aucun espace de fin et sur une seule ligne par . De plus – il le fait en lots approchant la taille ARGMAX – autant que possible à la fois. Et bien sûr, sed devrait gérer son travail aussi rapidement – il ne doit y avoir qu'une seule substitution globale par ligne d'input.

Les résultats fonctionnent comme ceci:

Certains Lorem Ipsum proviennent de http://www.lipsum.com :

 sed 's/\([.!?] *\)\{0,1\}/\1\\/g' <<LIPSUM | xargs printf %s\\n Section 1.10.32 of "de Finibus Bonorum et Mal orum", written by Cicero in 45 BC "Sed ut perspiciatis unde omnis iste natus er ror sit voluptatem accusantium doloremque lau dantium, totam rem aperiam, eaque ipsa quae a b illo inventore veritatis et quasi architect o beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia conse quuntur magni dolores eos qui ratione volupta tem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum q uia dolor sit amet, consectetur, adipisci vel it, sed quia non numquam eius modi tempora in cidunt ut labore et dolore magnam aliquam qua erat voluptatem. Ut enim ad minima veniam, quis ... ... reiciendis voluptatibus maiores alias consequ atur aut perferendis doloribus asperiores rep ellat." 1914 translation by H. LIPSUM 

… qui imprime …

 Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis ... ... reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat." 1914 translation by H.