Замена нескольких пустых строк одной пустой строкой в ​​vim / sed

42

Вопрос более или менее говорит сам за себя. Я знаю, что /^$/dбудут удалены все пустые строки, но я не вижу, как сказать «заменить две или более пустых строк одной пустой строкой»

Любые идеи?

Эндрю Болстер
источник

Ответы:

48

Если вы не используете vim или sed для какого-либо другого использования, у cat есть простой встроенный способ свернуть несколько пустых строк, просто используйте cat -s.

Если вы уже работали с vim и хотели остаться там, вы можете сделать это с помощью внутреннего поиска и заменить, выполнив: :%s!\n\n\n\+!^M^M!g(^ M - это визуальное представление новой строки, вы можете ввести его, нажав Ctrl+ vEnter), или сохранить себя печатать, просто обстреливая кошку :%!cat -s.

Калеб
источник
вау, не знал -sвариант cat - просто историческая справка, его нет в POSIX, но, кажется, он доступен в BSD и GNU cat.
maxschlepzig
2
Маркировка как «выигрыш» для :%!cat -s. Узнайте что-нибудь новое каждый день!
Эндрю Болстер
3
Я думаю, что вы также можете использовать \ r вместо ^ M, как это:%s!\n\n\n\+!\r\r!g
Нико Беллик
Мне это нужно было сегодня. Спасибо, Калеб! :)
Девид
19

Используйте \nдля обозначения новой строки в шаблоне поиска. Используйте Ctrl+ Mв тексте замены или обратной ссылке. Смотрите :help patternи :help sub-replace-special(ссылка с :help :s).

%s/\(\n\n\)\n\+/\1/
Жиль "ТАК - перестань быть злым"
источник
Можете ли вы объяснить, как работает шаблон поиска?
Сагар Джейн
Требование @sjmp: замените две или более пустых строки одной пустой строкой. Реализация: заменить три или более последовательных символов новой строки всего двумя символами новой строки. См. Руководство для объяснения конструкций, используемых в команде.
Жиль "ТАК - перестать быть злым"
Но зачем вам использовать группу, когда ее содержимое фиксировано?
Сабунку
@ Sabuncu Вам не нужно использовать группу. Но почему бы не использовать группу? Здесь я использовал группу, потому что вы не можете скопировать и вставить команду с новой строкой в ​​тексте замены: вам нужно вставить буквенный символ Ctrl + M, \nв тексте замены не работает.
Жиль "ТАК - перестань быть злым"
Теперь я понимаю, спасибо, что нашли время ответить.
Сабунку
6

Если в Vim, просто сделайте это:

:%!cat -s
coanor
источник
2
Вы можете добавить немного подробностей о том, как это работает, даже если это всего лишь цитата со manстраницы.
Джейсонвриан
Не работает на Windows 7
user674669
0

Использование Perl:

perl -00 -pe ''

-00 опция командной строки включает режим абзаца абзаца, что означает, что Perl читает текст абзац за абзацем, а не построчно.

Маджид Азими
источник
0

С помощью sed (GNU sed) 4.2.2:

sed -r '
  /^\s*$/ { 
    # blank line
:NEXT
    N # append next line to pattern space - if none, autoprint PS and exit
    s/^\s*$\n^\s*$//g;t NEXT # if 2 blank lines, clear PS and loop to NEXT
  }
  # else, autoprint PS and next/exit
' < $MYFILE
PJ_Finnegan
источник
-2

Я знаю, что это глупый код, но я хотел решить эту проблему менее чем за 10 минут, и это сработало

for file in /directory/*
do
  originalname=$file
  us='_'
  tempname=$file$us
  echo $originalname
  mv $originalname $tempname
  uniq $tempname $originalname
  rm $tempname
done
Махмуд Зальт
источник
1
uniqудаляет соседние равные линии Что не то, что хочет ОП.
pacholik
@pacholik он четко сказал: «Замена нескольких пустых строк одной пустой строкой» НЕ удаляйте соседние равные строки !!!
Махмуд Залт
3
Да, точно ...
pacholik