Как удалить несколько пустых строк из файла?

У меня есть текстовые файлы, которые я использую для записи заметок – просто обычный текст, обычно используя только файл cat >>. Иногда я использую пустую строку или две (просто возвращаю – символ новой строки), чтобы указать новый предмет / линию мысли. В конце каждой сессии – перед закрытием файла ctrl-D – я обычно добавляю много (5-10) пустых строк (возврат-ключ) только для разделения сеансов.

Это, очевидно, не очень клевер, но он работает для меня с этой целью. Тем не менее, я получаю много лишних пустых строк, поэтому я ищу способ удалить (большую часть) лишних строк. Есть ли Linux-команда (вырезать, вставить, grep, …?), Которые можно использовать напрямую с несколькими параметрами? В качестве альтернативы, у кого-нибудь есть идея для sed, awk или perl (ну и на любом скриптовом языке, хотя я бы предпочел sed или awk) скрипт, который будет делать то, что я хочу? Написание чего-то на C ++ (которое я действительно мог сделать сам), просто похоже на излишний …

Случай №1: мне нужен скрипт / команда, которая удаляет более двух (3 или более) последовательных пустых строк и заменяет их двумя пустыми строками. Хотя было бы неплохо, если бы он также мог быть изменен, чтобы удалить более одной строки (2 или более) и / или заменить несколько пустых строк только одной пустой строкой.

Случай №2: я мог бы также использовать скрипт / команду, которая удаляла бы одну пустую строку между двумя строками текста, но оставлять несколько пустых строк как есть (хотя удаление одной из пустых строк также было бы приемлемым).

PS: Да, я абсолютно должен изучать передовые (?) Sed и awk-скрипты, а также perl … это давно назрело. Но, как я и обещал сделать это, прочитав очень хорошую книгу Linux еще в 1995 году, я не буду так надеяться.

6 Solutions collect form web for “Как удалить несколько пустых строк из файла?”

Дело 1:

 awk '!NF {if (++n <= 2) print; next}; {n=0;print}' 

Случай 2:

 awk '!NF {s = s $0 "\n"; n++; next} {if (n>1) printf "%s", s; n=0; s=""; print} END {if (n>1) printf "%s", s}' 

Вы можете использовать uniq для свертывания нескольких экземпляров пустых строк в одну пустую строку, но также будут сбрасывать строки, содержащие текст, если они одинаковы и ниже друг друга.

Дело 1:

 perl -i -ane '$n=(@F==0) ? $n+1 : 0; print if $n<=2' 

Случай 2:

 perl -i -ane '$n=(@F==0) ? $n+1 : 0; print $n==2 ? "\n$_" : $n==1 ? "" : $_ ' 

Вы можете обратиться к Case # 1, как это, с помощью GNU sed:

 sed -r ':a; /^\s*$/ {N;ba}; s/( *\n *){2,}/\n\n/' 

То есть, собирайте пустые строки в пространстве шаблонов, а если есть более трех или более строк, уменьшите их до двух строк.

Чтобы присоединиться к линиям с одним интервалом, как в случае № 2, вы можете сделать это следующим образом:

 sed -r '/^ *\S/!b; N; /\n *$/!b; N; /\S *$/!b; s/\n *\n/\n/' 

Или в комментариях:

 sed -r ' /^ *\S/!b # non-empty line N # /\n *$/!b # followed by empty line N # /\S *$/!b # non-empty line s/\n *\n/\n/ # remove the empty line ' 

Следующее предложение Anthon использовать «uniq» …

Удалите передние, задние и дублированные пустые строки.

 # Get large random string. rand_str=; while [[ ${#rand_str} -lt 40 ]]; do rand_str=$rand_str$RANDOM; done # Add extra lines at beginning and end of stdin. (echo $rand_str; cat; echo $rand_str) | # Convert empty lines to random strings. sed "s/^$/$rand_str/" | # Remove duplicate lines. uniq | # Remove first and last line. sed '1d;$d' | # Convert random strings to empty lines. sed "s/$rand_str//" 

В одной длинной строке:

 (rand_str=; while [[ ${#rand_str} -lt 40 ]]; do rand_str=$rand_str$RANDOM; done; (echo $rand_str; cat; echo $rand_str) | sed "s/^$/$rand_str/" | uniq | sed '1d;$d' | sed "s/$rand_str//") 

Или просто используйте «cat -s».

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

 # Add extra blank lines at beginning and end. # These will be removed in final step. { echo; cat; echo; } | # Replace multiple blank lines with a single blank line. cat -s | # Remove first and last line. sed '1d;$d' 

В одной строке.

 { { echo; cat; echo; } | cat -s | sed '1d;$d'; } 

Это решение также заботится о последних пустых строках в файле:

 sed -r -n ' /^ *$/!{p;b} # non-blank line - print and next cycle h # blank line - save it in hold space :loop $b end # last line - go to end n # read next line in pattern space /^ *$/b loop # blank line - loop to next one :end # pattern space has non-blank line or last blank line /^ *$/{p;b} # last blank line: print and exit H;x;p # non-blank line: print hold + pattern space and next cycle ' 
  • как печатать поле между двойной цитатой
  • Использование sed для преобразования строк в строки
  • sed: портативное решение для соответствия «любому персонажу, но новой строке»,
  • В чем смысл использования нескольких восклицательных знаков в sed?
  • Используйте другой файл, чтобы извлечь часть строки, соответствующую grep, а также следующую строку, а затем сохранить в новый файл
  • как я могу прокомментировать / в разделе в исходном коде с sed или awk
  • Удалить строку перед пробелом
  • выходное содержание во втором случае
  • Как заменить многострочный код на sed?
  • sed и удалить строку между двумя шаблонами
  • Что означает <<<?
  • Linux и Unix - лучшая ОС в мире.