У меня есть куча файлов XML, содержащих тексты (транскрипции дневника). В конце предложений требуется, чтобы после точки было два пробела. На данный момент это делается частично, но не во всех случаях: иногда после точки перед первым символом следующего предложения остается только один пробел.

Я использую Gitbash для Windows и думаю, что sed - это команда, которую нужно использовать, но я не знаю правильного регулярного выражения. Я думаю, мне нужно найти:

точка пробела [какой-то другой символ]

И заменить на

точка пробела пробел [тот же следующий символ]

Например, сейчас у нас есть это:

<p>The spacing after this sentence (two whitespaces) is what is required. By contrast, this sentence has only a single space after the period. This is the next sentence, the last in a paragraph, which correctly has no whitespace at all after the period.</p>

Что мне нужно, так это то, что за каждым периодом следуют два пробела, кроме последнего в абзаце.

<p>The double whitespace after this sentence is what is required. This sentence now also has a double space after the period. This is the next sentence, the last in a paragraph, which correctly has no whitespace at all after the period.</p>

1
Peter Webster 26 Фев 2018 в 14:37

4 ответа

Лучший ответ

С sed вы можете сделать это:

sed -e "s/\. \</\.  /"

Вот изменения

$ sed -e "s/\. \b/\.  /g" test.txt > fixed.txt
$ diff test.txt fixed.txt
1c1
< <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vehicula placerat nisl, bibendum blandit tortor pharetra ut. Morbi nec tellus ultrices, porta felis et, dapibus diam. Phasellus vehicula ante ac urna elementum lacinia.</p>
---
> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.  Maecenas vehicula placerat nisl, bibendum blandit tortor pharetra ut.  Morbi nec tellus ultrices, porta felis et, dapibus diam.  Phasellus vehicula ante ac urna elementum lacinia.</p>
-1
nowox 26 Фев 2018 в 12:26

Вы можете использовать perl:

perl -pe 's-\. (?! )-\.  -g' test

Примере:

$ cat test
This is. A simple.  Test to check. That it works!
$ perl -pe 's-\. (?! )-\.  -g' test
This is.  A simple.  Test to check.  That it works!

Регулярное выражение \. (?! ) соответствует периоду, за которым следует пробел, за которым не следует другой пробел.

0
Maroun 26 Фев 2018 в 12:07

sed немного ограничен (можете ли вы использовать grep или perl?), В любом случае вы можете использовать регулярное выражение, подобное этому ( GNU sed специфично ):

sed -i -r 's/\. ([^ ])/.  \1/g'  <file>

< Сильный > Legenda

-i         # sed switch: replace inplace in the file passed as parameter
-r         # use extended regex 
/\. ([^ ]) # match a single dot followed by a space and by a not-space
/.  \1/    # replace with a dot follower by 2 spaces and by the previous non-space char
g          # apply multiple times per line

Регулярное выражение может быть уточнено при необходимости с помощью большего количества тестов.

Как свидетельствует @ghoti, ответ был специфичным для GNU sed . Я думаю, что более общий подход (без расширенного регулярного выражения и на месте) может быть:

sed 's/\. \([^ ]\)/.  \1/g' <input.file> > <output.file>
1
Giuseppe Ricupero 26 Фев 2018 в 14:05

Вы хотите найти все пробелы после точки и запомнить следующий символ. Затем замените на «.», И каким бы ни был запомненный персонаж. Запоминающая часть называется «теговым выражением».

Итак, ищите \. +([^ ]), что означает «точка, некоторые пробелы, [теговое выражение] что-то, что не является пробелом [конечное теговое выражение]»

Замените его . \1

Вот пример sed:

$ echo '>zzz. xxx.  yyy.<' | sed -r -e 's/\. +([^ ])/.  \1/g'
>zzz.  xxx.  yyy.<
1
Jonathan 26 Фев 2018 в 12:14