Должен быть лучший способ заменить единственные новые строки только?

Одна хорошая альтернатива top htop. Проверьте его, это намного более удобно для пользователя, чем регулярная вершина.

27
05.02.2011, 01:21
11 ответов

Можно использовать awk как это:

$ awk ' /^$/ { print; } /./ { printf("%s ", $0); } ' test

Или если Вам нужна дополнительная новая строка в конце:

$ awk ' /^$/ { print; } /./ { printf("%s ", $0); } END { print ""; } ' test

Или если Вы хотите разделить абзацы новой строкой:

$ awk ' /^$/ { print "\n"; } /./ { printf("%s ", $0); } END { print ""; } ' test

Эти команды awk используют действия, которые охраняют шаблоны:

/regex/

или

END

Следующее действие только выполняется, если шаблон соответствует текущей строке.

И ^$. символы имеют особое значение в регулярных выражениях, где ^ соответствует началу строки, $ конец и . произвольный символ.

18
27.01.2020, 19:39
  • 1
    Это хорошо, хотя я предпочел бы сохранять пустую строку между абзацами. Я предполагаю, что Вы могли сделать что-то вроде этого путем добавления дополнительной новой строки где-нибудь в первой команде печати? Кроме того, что /./ выполнение: это, кажется, действует как и else для /^$/ представьте в виде строки соответствие, которое правильно? –  Seamus 04.02.2011, 23:26
  • 2
    @Seamus менее чем 1 МБ, уверенный - просто, заменяют первую печать (обновил ответ)-/./, соответствует всем строкам, которые являются по крайней мере одним символом долго, т.е. дополнением/^ $ / шаблон, который соответствует только пустым строкам. –  maxschlepzig 05.02.2011, 12:39

Используйте Awk или режим абзаца Perl для обработки абзаца файла абзацем, где абзацы разделяются пустыми строками.

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
'

Конечно, так как это не анализирует (La) TEX, он ужасно искалечит комментарии, дословные среды и другой специальный синтаксис. Можно хотеть изучить DeTeX или другие преобразователи (La)TeX-to-text.

9
27.01.2020, 19:39

Решение Sed

$ sed -e ':a;N;$!ba;s/\(.\)\n/\1 /g' -e 's/\n/\n\n/' test.text

Отметьте, это в этом решении :a создает маркировку и использует a команда.

Замена нескольких пробелов

Использовать tr: $ tr -s ' ' <test.text

8
27.01.2020, 19:39

Если я понял правильно, пустая строка подразумевает две последовательных новых строки, \n\n.

Если так, одно возможное решение состояло бы в том, чтобы устранить все исключительные случаи новых строк.

В Perl предварительное утверждение является одним способом достигнуть этого:

$ perl -0777 -i -pe 's/\n(?=[^\n])//g' test
  • -0777 флаг эффективно хлебает целый файл в единственную строку
  • -p говорит жемчугу печатать строку, это продолжает работать по умолчанию
  • -i указывает оперативное редактирование
  • Глобальное соответствие гарантирует, что со всеми единственными случаями новой строки имеют дело
8
27.01.2020, 19:39
  • 1
    Одна проблема, которую это имеет, состоит в том, что нет никаких пробелов между предложениями. –  Steven D 05.02.2011, 00:10

После наблюдения жемчуга Gilles и awk компактных примеров, я отказывался отправить это, но я уже прошел осуществление, и это - функционирующий сценарий, который обоснованно документируется; одна только эта точка может представлять интерес для некоторых.. (sed с комментариями!:)

Этот сценарий полагает, что пустые строки пробел, даже если они содержат пробел.
Несколько пробелов в тексте сжаты к одиночному пробелу.
Запаздывающий пробел удален из текстовых строк. Последовательные пустые строки сворачиваются к одной строке. Сценарий оставляет вершину и нижние пустые строки неповрежденными.

Для чего-то большего чем большинство тривиальных сценариев, sed может быть записано намного более легко в структурированной форме как отдельный файл сценария. Вот такой пример.

использование расширило regex синтаксис
вызов: $ sed-rf текстовый файл сценария

  :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

Примечание: flush, в комментариях, средствах: отправьте пространство шаблона во внутреннюю обработку stdout sed. Это не значит определенную печать для stdout. Вывод зависит от sed's -n опция. например, q управляйте сбросом средств и выходом... Сравните эти два отрывка: echo x |sed -e q печать x, echo x |sed -ne q печать ничто, тогда как использование p команда распечатала бы 'x' дважды или однажды, в зависимости от -n опция.

5
27.01.2020, 19:39
  • 1
    +1 для хороших комментариев. Я видел слишком много программ без комментариев вообще. –  David Cary 09.05.2013, 18:17

Здесь является еще одним sed решение, которое связывает все строки в sed"держите пространство" так, чтобы мы получили одну длинную строку, которая наконец копируется в "пространство шаблона" для сопоставления с образцом.

Поскольку новые строки будут сохранены в заключительной длинной строке в sed"шаблон располагает с интервалами", пустые строки с точки зрения двойных разрывов строки [^\n]\n\n[^\n] может быть подобран и изменен к [^\n]\n[^\n].

Для получения дополнительной информации посмотрите, например, sed и Многострочный Поиск и Замена.

text='
line 1

line 2
line 3





line 4


line     5



line 6
line 7

line 8
'

# FreeBSD sed
# first sed deletes first / last line if empty and squeezes multiple spaces
printf '%s' "$text" |
sed -e '1{/^$/d;}' -e '${/^$/d;}' -e '/[[:space:]]\{2,\}/s// /g' | 
sed -n -e '1h;1!H;${;g;/\([^[:cntrl:]]\)\n\n\([^[:cntrl:]]\)/s//\1\
\2/g;p;}' |
nl -b a


# GNU sed
# alternative using ...;x;... instead of ...;g;...
# cf. man sed | less -p '\]x'
printf '%s' "$text" |
gsed -e '1{/^$/d;}' -e '${/^$/d;}' -e '/[[:space:]]\{2,\}/s// /g' | 
gsed -E -n '1h;1!H;${;x;/([^\n])\n\n([^\n])/s//\1\
\2/g;p;}' | 
nl -b a


# remove all the single linebreaks but leave the double linebreaks intact
printf '%s' "$text" | 
   sed -n -e '1h;1!H;${;g;/\([^[:cntrl:]]\)\n\([^[:cntrl:]]\)/s//\1 \2/g;p;}' | 
   nl -b a
4
27.01.2020, 19:39

Это могло бы быть старой школой:

(echo ".pl 1" ; echo ".ll 80" ; echo ".ad l" ; cat your_file) | nroff

Это произведет Ваш выровненный по левому краю текст (.ad l), с длиной строки 80 (.ll 80). Опция длины страницы (.pl) говорит текстовому процессору делать дополнение страницы для длины страницы 1, таким образом, никакое дополнение страницы.

Если Вы хотите все свои абзацы на одной строке, Вы могли бы использовать большое количество для .ll:

(echo ".pl 1" ; echo ".ll 1000000" ; echo ".ad l" ; cat your_file) | nroff

человек 7 groff для большего количества параметров форматирования.

3
27.01.2020, 19:39

Это оказывается этим с auto-fill-mode на, emacs делает довольно хорошее задание для моих простых вариантов использования только с M-q...

0
27.01.2020, 19:39
  • 1
    Детали какой auto-fill-mode действительно зависит, на каком главном режиме Вы имеете активный. номер –  dmckee --- ex-moderator kitten 12.08.2011, 23:14

(восстановление древнего вопроса)

Это, кажется, точно что fmt и par для - переформатирование абзаца. Как Вы (и также как много программ) они определяют границы абзаца как одну (или больше) пустые строки. Попытайтесь передать свой текст по каналу через один из них.

fmt стандартная утилита Unix и может быть найдена в GNU Coreutils.

par значительно улучшенный fmt записанный Adam M. Costello, который может быть найден по http://www.nicemice.net/par/ (это было также упаковано для нескольких дистрибутивов, включая debian - я упаковал его для debian в Jan 1996, хотя существует новый специалист по обслуживанию для pkg теперь.).

6
27.01.2020, 19:39
sed -e'/./{H;$!d;}' -e'x;s/\n//g'

sed добавит любую строку к H старому пространству, которое содержит хотя бы один символ. Сразу после этого d возвысит все, кроме, возможно, последнего. Единственные строки, которые могут остаться пустыми, и именно на этих строках, когда sed exменяет значения пробела удержания и шаблона и удаляет все накопленные \newline символы.

Если вы хотите, чтобы строки, которые содержат только <табы> или <пробелы> считались пустыми, замените вышеприведенный адрес /./ на /[^[:пробел:]]/. Чтобы также сжать пробелы сделайте:

 sed -e'/./{H;$!d;}'    \
     -e'x;s/\n//g'      \
     -e's/\([[:blank:]]\)*/\1/g'
6
27.01.2020, 19:39

В Emacs я иногда использую этот regex:

^J\([^^J]\) -> \1

означает:

заменить каждую новую строку, за которой следует что-то, что НЕ является новой строкой, только той вещью, которая следует за новой строкой. Таким образом, я избавляюсь от всех новых строк в параграфе, но сохраняю параграфы (двойные строки)

1
27.01.2020, 19:39

Теги

Похожие вопросы