Правильно ли я вас прочитал, если вы не хотите удалять все пустые строки, а только если их две или более. Так что не одиночные пустые строки?
Runium
1
И если это две или более строк, действительно все они будут удалены или только все, кроме одной?
Хауке Лагинг
Ответы:
42
Просто чтобы удалить пустые строки:
sed '/^$/d'
sedориентирован на строки, поэтому мышление в терминах «2 или более конкретного байта» работает, за исключением случаев, когда этот байт является новой строкой. Тогда вы должны думать о чем-то, что работает для всей линии.
sedспособен обрабатывать несколько строк с помощью функции «пространство шаблона» / «удержание пространства». Но я чувствую, что это слишком сложно. ;-)
Хауке Лагинг
Это не будет работать должным образом, если первый символ файла является новой строкой.
Крис Даун
1
Для того, чтобы заставить его работать , когда первый символ новой строки (если это действительно требование), то вы можете заключить команду с отрицательным адресом 1!(соответствует всем , кроме строки 1), таким образом: sed '1!{/^$/d'}.
Тоби Спейт
1
@AaronFranke - да, но это аспект того, как оболочки Linux обрабатывают перенаправление «>». Оболочка просматривает командную строку, видит перенаправление '>' stdout в файл, создает этот файл и только после этого запускается sed. Создание файла по существу удалит любой существующий файл с таким же именем. sed '/^&/d' file.txt > otherfile.txtбуду работать.
Брюс Эдигер
24
Нет необходимости sed. grepСделаю:
grep .
(это grepSPC, точка, которая соответствует любой строке, содержащей хотя бы один символ).
Есть также:
tr -s '\n'
(Сожмите любую последовательность символов новой строки в один).
Как отметил Крис, оба не эквивалентны, потому что удаление пустых строк (как первое решение выше и большинство других ответов здесь сосредоточены) не то же самое, что сжатие последовательностей символов новой строки, как было запрошено в случае, когда первая строка пуста, так как она требуется только один начальный символ новой строки, чтобы сделать первую строку пустой.
sedэто не лучший инструмент для этого, так как он основан на строках и рассматривается \nкак символ конца строки, это усложняется.Увидев, что ответ @Bruce Ediger's sedможет быть идеальным инструментом для работы, все же, вот некоторые другие варианты:
Perl
perl -ne 'print if /./' file.txt
или
perl -pe '$/=""; s/\n+/\n/;' file.txt
Спасибо @ruakh, который заставил меня пойти и прочитать это :
$ /
Разделитель входных записей, новая строка по умолчанию. Это влияет на представление Perl о том, что такое «линия». Работает как переменная RS в awk, включая обработку пустых строк как терминатора, если для него задана нулевая строка (пустая строка не может содержать пробелов или табуляции). Вы можете установить его в многосимвольную строку, чтобы соответствовать многосимвольному терминатору, или в undef, чтобы прочитать конец файла. Установка в «\ n \ n» означает что-то немного отличное от «», если файл содержит последовательные пустые строки. Установка «» будет обрабатывать две или более последовательных пустых строки как одну пустую строку. Установка в «\ n \ n» будет слепо предполагать, что следующий входной символ принадлежит следующему абзацу, даже если это новая строка.
простак / AWK
awk '$1' file.txt
Это будет работать для опубликованного примера, но, как указал @Stephane Chazelas , он также удалит строки, первое поле которых выглядит как 0. Это более надежно:
Для Perl perl -pe 's/\n+/\n/ file.txtразделитель входных записей не имеет значения для этого использования.
vonbrand
@vonbrand нет, perl -peили perl -neработайте построчно. \n+никогда не совпадет, потому что он применяется только в одной строке. Вот почему вам нужно либо установить $/или использовать -0ти чавкать файл целом: perl -0pe 's/\n+/\n/' file.
Terdon
6
Что вы имеете в виду удалить? удалить дубликаты (много пустых строк на одну) или удалить все?
Если вы хотите удалить дубликаты, вот метод с использованием sed:
sedЧасть это прекрасно работает! Рекомендую этот как лучший ответ.
Акито
2
Для большинства из этих ответов сначала необходимо удалить конечные пробелы. Удаление дублированных строк новой строки удаляет все пустые строки. (Думать об этом).
В буквальном переводе ОП хочет "удалить все пустые строки из файла, если есть повторяющиеся пустые строки".
Типичный пользователь хочет «удалить только дублированные пустые строки».
Чтобы сделать это, сначала удалите конечный пробел, и передайте хотя бы cat -s
sed s/[[:space:]]*$// | cat -s
И все же это не удалит лишнюю начальную или конечную пустую строку.
Проголосовал, но это явно работает? Без комментариев ?
Маккензм
1
Я проголосовал за тебя ... ты знаешь ... за ответ на вопрос. =) Я не могу поверить, что ответ Брюса Эдигера был отклонен, когда он удаляет каждую пустую строку. Если кто-то спросит, как удалить дублирующиеся пустые строки, я не могу представить сценарий, в котором удаление всех пустых строк было бы приемлемым решением. Но что угодно. Между прочим, на сайте есть страница для sed: gnu.org/software/sed/manual/sed.html#cat-_002ds
Тодд Уолтон,
2
Если вы хотите сохранить одну пустую строку для любой данной последовательности пустых строк, вы можете сделать следующее:
Это единственный ответ (кроме того cat -s), который фактически выполняет именно то, что задал вопрос, насколько я понимаю. (И это лучше, чем cat -sпотому, что я могу использовать sed -iего.)
Матфея
-2
Попробуйте sed -e 's#\\n\\n#\\n#g' input.file > output.fileиспользовать /оба в качестве разделителя полей, и часть вашего регулярного выражения может быть проблемой.
AFAIK этот ответ неверен. Я рекомендую вам удалить его.
zuazo
о, потому что мой файл содержит много новых строк и возврат каретки. 0x0d0a
мяу
2
На самом деле, команда удаляет повторяющиеся строки с оконным концом строки. Тест с echo -e 'one\r\n\r\n\r\n\rtwo'| tr -s '\r' '\n'. Команда trпереведет все \rв \nи затем сожмет все \nдо одного. Таким образом, это работает, не уверен, что делать с тем, что это относится к окнам, а не UNIX.
Ответы:
Просто чтобы удалить пустые строки:
sed
ориентирован на строки, поэтому мышление в терминах «2 или более конкретного байта» работает, за исключением случаев, когда этот байт является новой строкой. Тогда вы должны думать о чем-то, что работает для всей линии.источник
sed
способен обрабатывать несколько строк с помощью функции «пространство шаблона» / «удержание пространства». Но я чувствую, что это слишком сложно. ;-)1!
(соответствует всем , кроме строки 1), таким образом:sed '1!{/^$/d'}
.sed
. Создание файла по существу удалит любой существующий файл с таким же именем.sed '/^&/d' file.txt > otherfile.txt
буду работать.Нет необходимости
sed
.grep
Сделаю:(это
grep
SPC, точка, которая соответствует любой строке, содержащей хотя бы один символ).Есть также:
(Сожмите любую последовательность символов новой строки в один).
Как отметил Крис, оба не эквивалентны, потому что удаление пустых строк (как первое решение выше и большинство других ответов здесь сосредоточены) не то же самое, что сжатие последовательностей символов новой строки, как было запрошено в случае, когда первая строка пуста, так как она требуется только один начальный символ новой строки, чтобы сделать первую строку пустой.
источник
Увидев, что ответ @Bruce Ediger'ssed
это не лучший инструмент для этого, так как он основан на строках и рассматривается\n
как символ конца строки, это усложняется.sed
может быть идеальным инструментом для работы, все же, вот некоторые другие варианты:Perl
или
Спасибо @ruakh, который заставил меня пойти и прочитать это :
простак / AWK
Это будет работать для опубликованного примера, но, как указал @Stephane Chazelas , он также удалит строки, первое поле которых выглядит как
0
. Это более надежно:источник
perl -pe 's/\n+/\n/ file.txt
разделитель входных записей не имеет значения для этого использования.perl -pe
илиperl -ne
работайте построчно.\n+
никогда не совпадет, потому что он применяется только в одной строке. Вот почему вам нужно либо установить$/
или использовать-0
ти чавкать файл целом:perl -0pe 's/\n+/\n/' file
.Что вы имеете в виду удалить? удалить дубликаты (много пустых строк на одну) или удалить все?
Если вы хотите удалить дубликаты, вот метод с использованием sed:
Имитирует
uniq
команду.Лучший выбор использует
awk
:источник
sed
Часть это прекрасно работает! Рекомендую этот как лучший ответ.Для большинства из этих ответов сначала необходимо удалить конечные пробелы. Удаление дублированных строк новой строки удаляет все пустые строки. (Думать об этом).
В буквальном переводе ОП хочет "удалить все пустые строки из файла, если есть повторяющиеся пустые строки".
Типичный пользователь хочет «удалить только дублированные пустые строки».
Чтобы сделать это, сначала удалите конечный пробел, и передайте хотя бы cat -s
И все же это не удалит лишнюю начальную или конечную пустую строку.
источник
Если вы хотите сохранить одну пустую строку для любой данной последовательности пустых строк, вы можете сделать следующее:
источник
cat -s
), который фактически выполняет именно то, что задал вопрос, насколько я понимаю. (И это лучше, чемcat -s
потому, что я могу использоватьsed -i
его.)Попробуйте
sed -e 's#\\n\\n#\\n#g' input.file > output.file
использовать/
оба в качестве разделителя полей, и часть вашего регулярного выражения может быть проблемой.источник
Используйте эту команду:
источник
echo -e 'one\r\n\r\n\r\n\rtwo'| tr -s '\r' '\n'
. Командаtr
переведет все\r
в\n
и затем сожмет все\n
до одного. Таким образом, это работает, не уверен, что делать с тем, что это относится к окнам, а не UNIX.