Когда у вас возникла одна из этих проблем, а файл не гигантский, одним из лучших инструментов для работы является perl в режиме undef $/
, который позволяет читать весь файл как один большой строка; это позволяет вам сопоставить \n
, как и любой другой символ.
На уровне символов, при условии, что ни в одной строке нет завершающих горизонтальных пробелов, пустая строка - это два символа новой строки в строке; две пустые строки - это три символа новой строки и так далее. Чтобы удалить пустую строку, вы удалите один из двух символов новой строки. Теперь, если вы просто напишите s/\n\n/\n/g
, это будет делать больше, чем вы хотите, потому что \n\n
будет соответствовать парам новых строк в пределах длинных серий новых строк. Таким образом, вам нужна конструкция, которая будет соответствовать двум символам новой строки подряд, но только в том случае, если им не предшествует или не следует больше новых строк. Вот для чего нужны проверочные утверждения .
perl -pe 'BEGIN { undef $/ } s/\s+$//mg; s/(?<!\n)\n\n(?!\n)/\n/sg'
должен сделать эту работу. Это будет иметь побочный эффект удаления конечных пробелов, если таковые имеются, из каждой строки файла. Если вы хотите удалить как двойные пустые строки, так и одиночные пустые строки (но все же не тройные пустые строки), вам просто нужно отрегулировать середину второго RE:
perl -pe 'BEGIN { undef $/ } s/\s+$//mg; s/(?<!\n)\n{2,3}(?!\n)/\n/sg'