2014-01-17 2 views
1

Мне нужна команда, чтобы добавить период (полная остановка) в конец абзаца. Я пробовал следующую команду:Добавить период в конце абзаца

sed '/ +$/s/$/ ./' $FILENAME 

но не работает !!

+0

@FredrikPihl, что это та же команда, что я пытался и не делать то, что мне нужно? –

+0

Ошибка копирования-вставки, поэтому я удалил ее –

+1

Что такое абзац в вашем случае? Это линия, или это набор строк, разделенных пустой линией? –

ответ

2
awk -v RS="" -v ORS=".\n\n" 1 file 

Это переопределяет входной разделитель записей, чтобы быть пустым, так что AWK читает пустые строки, разделенные пункты в виде одной записи , Он устанавливает разделитель выходной записи как точку и 2 символа новой строки. Фактическая программа awk, 1 простая печать каждой записи.

Один побочный эффект заключается в том, что любые последовательные пустые строки будут свернуты в одну пустую строку.


OK, Sheesh

awk -v RS="" -v ORS="\n\n" '{sub(/\.?$/,".")} 1' 

В действии: (трубопроводы через cat -n только отметить, что новые строки)

echo -e "a.\n\nb\nc\n\n\nd" | 
awk -v RS="" -v ORS="\n\n" '{sub(/\.?$/,".")} 1' | 
cat -n 
1 a. 
2 
3 b 
4 c. 
5 
6 d. 
7 

Там есть дополнительный символ новой строки в конце , из-за ORS.


И, в качестве бонуса, вот немного Perl, который сохраняет интервал между параграфами:

echo -e "a.\n\nb\nc\n\n\nd" | perl -0777 -pe 's/\.?(\n(\n+|$))/.$1/g' | cat -n 
1 a. 
2 
3 b 
4 c. 
5 
6 
7 d. 
+0

отлично, что я NEED –

+0

Вы сделали это снова, я заблудился в http://www.gnu.org/software/gawk/manual/html_node/Multiple-Line.html и пропустил период в 'ORS'-части ... +1 Но, если я забегаю в своем примере-тексте, я получаю дополнительный период в конце первого предложения ... –

+0

@FredrikPihl: Действительно: иначе элегантное и сжатое решение Гленна _uncondition_ добавляет '.', даже если абзац уже заканчивается на одном - просто ограничение, о котором нужно знать. – mklement0

0

Это должно работать:

sed "s/[[:alpha:]]\+[^\.]$/\./" $FILENAME 
+0

также я попробую, он ставится точка остановки на пустой строке! также если линия имеет точку останова, она добавит еще одну точку остановки! –

+0

Я отредактировал ответ, вы можете проверить его? – higuaro

+0

К сожалению, это не работает! –

1

Не очень хорошо, но это, кажется, работает ...

$ cat input 
This is a paragraph with some text. Some random text that is not really important. 

This is another paragraph with some text. 
However this sentence is still in the same paragraph 

$ tr '\n' '@' < input | sed 's/\([^.]\)@@/\[email protected]@/g' | tr '@' '\n' 
This is a paragraph with some text. Some random text that is not really important. 

This is another paragraph with some text. 
However this sentence is still in the same paragraph. 
+0

не работает !! , также я не могу понять что-нибудь из этой команды !! –

+0

@Hassan - он просто заменяет каждую новую строку символом '@' с результатом, что все одна строка, тогда я просто заменяю символ шаблона, который не является периодом, а затем 2 @@ ' включают период. И последняя команда 'tr' вернула новые строки. Могучий Глен Джекман показывает, как это сделать на самом деле! –

0

Чистый решение с использованием трюма сохранить все строки из и добавить период непосредственно перед печатью:

sed -ne ' 
    ## Append current line to "hold space". 
    H 
    ## When found an empty line, get content of "hold space", remove leading 
    ## newline added by "H" command, append a period at the end and print. 
    ## Also, clean "hold space" to save following paragraph. 
    /^$/ { g; s/^\n//; s/\(.*\)\(\n\)/\1.\2/; p; s/^.*$//; h; b } 
    ## Last line is a bit special, it has no following blank line but it is also 
    ## an end of paragraph. It is similar to previous case but simpler. 
    $ { x; s/^\n//; s/$/./; p } 
' infile 

Предполагая, infile с содержанием:

one 
two 

three 

four 
five 
six 

Это дает:

one 
two. 

three. 

four 
five 
six. 
+0

Человек, похоже, что сценарий youre решает мою проблему, но этот тип кода я никогда не вижу, не могли бы вы объяснить мне, что это? –

+0

@ Hassan: Команды 'sed' с комментариями чередуются. Для лучшего объяснения каждой инструкции смотрите руководство. – Birei

+0

Да, я google, и я это понимаю, спасибо за ваше усилие –

1

Использование СЭД.

sed ':loop;$!{N;b loop};s/[^\.]$/&./;s/\([^\.]\)\(\n[ \t]*\n\)/\1.\2/g' file 

объяснение

:loop;$!{N;b loop} сохранит все строки в шаблоне пространства, ограниченного переводом строки. s/[^.]$/&./ добавит. если последний абзац не имеет точки в конце. s/\([^\.]\)\(\n[ \t]*\n\)/\1.\2/g добавит точку до \ n \ n, которая будет идентифицироваться как новый абзац.

+1

+1 для сохранения исходного количества пустых строк между абзацами и правильной обработки уже завершенных абзацев (в отличие от более сжатого и читаемого решения @ glennjackman). На платформах, где доступны расширенные регулярные выражения (например, Linux), мы получаем более читаемые: 'sed -r ': loop; $! {N; b loop}; s /[^.]$/ &./; s/([^.]) (\ n [\ t] * \ n)/\ 1. \ 2/g'' файл. Чтобы заставить его работать с OSX (обратите внимание на сплайсинговые литералы новой строки): 'sed -E ': loop' $ '\ n' '$! {N; b loop' $ '\ n' '}; s/[^ .] $/&./; s/([^.]) (\ N [\ t] * \ n)/\ 1. \ 2/g 'file' – mklement0

1
  1. Накопить «абзацы» в удержании. Продолжайте накапливать до тех пор, пока строка ввода содержит любые непространственные символы.

  2. Когда вы получаете пустую/пустую строку, предположим, что у вас есть накопленный абзац. Поменяйте текущую (пустую) линию на удержание. Замените последний непространственный символ в пространстве шаблонов (который теперь является «абзацем», который вы накапливали) с самим собой, за которым следует точка, если только этот символ не является точкой. Распечатайте результат.

Я думаю, что это делает:

$ cat test 
this is a test line. one-line para 

this is a test line. one-line para. with period. 

this is a 
two line para- 
graph with dot. 

this is a 
two-line paragraph 
with no dot 

also works on last 
line of file 
$ sed -n \ 
    -e '/^[[:space:]]*$/{x;s/\([^.[:space:]][[:space:]]*\)$/\1./;p;n;}' \ 
    -e '/^[[:space:]]*[^[:space:]]/H' \ 
    test 

this is a test line. one-line para. 

this is a test line. one-line para. with period. 

this is a 
two line para- 
graph with dot. 

this is a 
two-line paragraph 
with no dot. 
Смежные вопросы