Как удалить пустые комментарии с sed?

Я нашел решение своей проблемы здесь. Если я использую md5crypt команда для генерации моего пароля я должен войти --md5 между моим password и зашифрованный пароль. Теперь это работает.

Так, перед title записи в моем /boot/grub/menu.lst файл у меня есть строка с паролем. Это теперь читает

password --md5 encrypted_password.

На основе моего опыта кажется, что установка пароля для Загрузчика через YaST не работает правильно на OpenSuSE 11.2. Я еще не проверил для наблюдения при добавлении a --md5 к зашифрованному паролю, обеспеченному YaST, заставил бы это работать, я только попробовал md5crypt метод с этим.

2
05.05.2014, 22:35
5 ответов

sed работает над одной строкой за один раз. Используйте жемчуг вместо этого:

perl -0777 -pe 's,\s*/\*[*\s]*\*/\s*, ,gs'

Это преобразует пустой комментарий и все пробелы вокруг этого к одиночному пробелу (необходимый, иначе int/* */i был бы превращен inti иначе, например). Теперь, это означает, что, если у Вас есть последовательные пустые комментарии, у Вас будут последовательные пробелы, таким образом, можно будет захотеть изменить его на:

perl -0777 -pe 's,\s*(?:/\*[*\s]*\*/\s*)+, ,gs'

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

perl -0777 -pe 's,(\s*)(?:\s*/\*[*\s]*\*/)+(\s*\n|\s*),"$1$2"=~/\n/?"\n":" ",ges'

Таким образом, если были новые строки вокруг комментариев, замены новой строкой (и исходное добавление отступа после новой строки после комментариев) или пространство иначе.

Это возможно с жемчугом, потому что жемчуг regexp оператор чередования вопреки другому regexp механизму, не пытайтесь найти самое долгое соответствие, но посмотреть на каждую часть чередования в свою очередь, пока каждый не соответствует.

Теперь, если Вы хотите проигнорировать пустые комментарии, которые могут произойти в строках (как "/***/"), это становится немного более хитрым особенно, когда необходимо принять во внимание оставленные двойные кавычки или двойные кавычки в одинарных кавычках. Но, еще раз чередование жемчуга regexp оператор приходит на помощь:

perl -0777 -pe 's,(\s*)(?:\s*/\*[*\s]*\*/)+(\s*\n|\s*)|(/\*.*?\*/|//.*?\n|"(?:\\.|.)*?"|'\''(?:\\.)?.*?'\''|.[^"/'\'']*),"$3"or"$1$2"=~/\n/?"\n":" ",ges'

Идея состоит в том, что это, regexp соответствует целому файлу, но в различных альтернативах для того большого чередования, которое работает немного как токенизатор.

В основном это идет через файл и разделяет его на маркеры. Текст рассматривают как последовательность маркеров, которые являются или пустыми комментариями, мы смотрим, руда дважды заключенные в кавычки строки или единственно заключенные в кавычки символы (с возможно Escape как '\'' или '\033'), или что-либо еще.

Маркеры, которые являются пустыми комментариями, которые мы ищем, заменяются пространством или новой строкой как выше, что-либо еще заменяется собой. Таким образом, это должно теперь смочь обработать исходные данные как

/* comments with " unmatched quotes ' */ /* */
  f('"', "/***/" /***/, "\"", "/****/")

правильно. Теперь, не будучи знакомым с java синтаксис, я предполагаю, что могли бы быть угловые случаи, где это не работает, таким образом, эксперт Java смог бы улучшить его (например, в C, необходимо будет объяснить trigraphs, или обратные косые черты могут использоваться для выхода из новых строк, таким образом, он пропустил бы a /* это было повреждено в середине как /\<LF>*, это могло бы быть то же в Java, таким образом, Вы могли улучшить тот код для принятия этого).

3
27.01.2020, 22:07
  • 1
    Эти работы для меня, но удаляет некоторые новые строки, что я не хочу. –  Konrad Höffner 22.10.2012, 15:53
  • 2
    +1, для удаления только комментариев просто удаляют \s* от шаблона: perl -0777 -pe 's,/\*[*\s]*\*/, ,gs' –  Nahuel Fouilleul 22.10.2012, 18:00
  • 3
    На самом деле sed может работать над несколькими строками..., просто усложнил –  daisy 22.10.2012, 18:44
  • 4
    @warl0ck, да, хотя то число ограничено в большинстве sed реализаций, POSIX, только требующий шаблона, и держите пространство, чтобы смочь содержать 10 x символов LINE_MAX, где LINE_MAX, IIRC может быть всего 2048. Так, в общем/портативном случае sed не подходит для многострочной обработки. –  Stéphane Chazelas 22.10.2012, 19:20
  • 5
    Хороший, пока существует нет /* или */ в строке... –  Gilles 'SO- stop being evil' 23.10.2012, 01:23

Попытка распечатать ожидаемый вместо того, чтобы удалить, который более прост в этом случае:

sed -n '/[^ \/\*]/p' file

Это пытается распечатать все те строки, которые содержат что-либо кроме/, пространство или *

0
27.01.2020, 22:07
  • 1
    Между прочим, это уничтожит код в случае, если непустой комментарий запускается с /* строка или концы с */ строка. –  rush 22.10.2012, 15:27
  • 2
    @rush: это привычка.. непустой комментарий содержит что-то другое, чем наклонная черта, asterik или пространство.. таким образом это решение должно хорошо работать.. –  Guru 22.10.2012, 15:34
  • 3
    это будет. К сожалению, я не могу сделать многострочное сообщение здесь в комментариях. Я имею в виду многострочные комментарии как: 1-я строка: /* 2-я строка * comment и продержитесь тот */. С Вашим кодом будет удален 1-й и последний, но середина каждый останется. –  rush 22.10.2012, 15:46
  • 4
    Это не работало на меня, это удалило / **\n bla bla bla\n */ –  Konrad Höffner 22.10.2012, 15:50
  • 5
    @rush: понятый Ваша мысль... да, его неправильное, среднее останется... –  Guru 22.10.2012, 16:01
sed '/\/\*/{:a;N;/\*\//!ba};/^\s*\/\*\+[*\s\n ]*\*\/\s*$/d'

где

/\/\*/{:a;N;/\*\//!ba}

добавит всю строку комментариев в одну

/^\s*\/\*\+[*\s\n ]*\*\/\s*$/d

проверит, является ли это пустой комментарий, и удалите его, если это.

0
27.01.2020, 22:07

Вот что-то, что я нашел в Интернете несколько лет назад, работах для нескольких строк,

#!/bin/sed -f
# if no /* get next
/\/\*/!b
# here we've got an /*, append lines until get the corresponding
# */
:x
/\*\//!{
N
bx
}
# delete /*...*/
s/\/\*.*\*\///
0
27.01.2020, 22:07
  • 1
    По крайней мере, по сравнению с другими ответами sed, синтаксис является стандартным. Однако это не отвечает на вопрос (это удаляет все комментарии не только пустые), и не будет работать правильно, если будет несколько комментариев на строку. –  Stéphane Chazelas 23.10.2012, 20:17

В то время как это возможно с sed, он является сложным для распознавания многострочных комментариев, особенно если Вы хотите быть осторожными и правильно обработать /* или */ в литеральной строке или a // комментарий.

Исходные файлы являются достаточно обычно небольшими для установки полностью к памяти большим полем, таким образом, нет никакого преимущества в обработке их линию за линией. Загрузите весь файл в памяти с языком, таким как Perl и Python, затем сделайте частичную токенизацию. Вот минимально непротестированная программа Perl.

perl -0777 -ne '
    while ($_ ne "") {
        if (s~\A[^/"]+|\A\x27\\?.\x27|\A"(?:[^\\"]|\\.")~~) { print $&; } # not a comment
        elsif (s~\A//(.*)$~~m) { $c = $&; print $c if $1 =~ /\S/ } # // comment
        elsif (s~\A/\*(.*?)(\*/|\z)~~) { # /*comment*/
            $c = $&;
            if ($1 =~ /\A[^\n\t *]/ || !$2) {
                print $c; # non-empty or non-terminated comment
            } else {
                $c =~ s/[^\n]//g; # empty comment: retain the newlines
                print $c;
            }
        } else {s~\A.~~; print $&;}
    }

'

0
27.01.2020, 22:07
  • 1
    @sch вставляется Копией? Нет, введенный непосредственно в моем браузере и полностью непротестированный. –  Gilles 'SO- stop being evil' 23.10.2012, 15:01
  • 2
    , который это получает там, но там все еще является несколькими проблемами (пропавшие без вести * в кавычках, скучая по некоторым s флаги к заменам, по крайней мере). Я был бы вполне впечатлен, если Вы могли бы предложить решение, не тестируя его. –  Stéphane Chazelas 23.10.2012, 17:11

Теги

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