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

Вопрос или проблема

У меня есть большой патч (более 80 тысяч строк), и в этом патче я хочу удалить строки, содержащие плюс, и оставить только одну строку.

Например:

+$as_echo "$CC_FOR_BUILD" >&6; }
+
+
+
+
+case `pwd` in
+  *\ * | *\    *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"

Чтобы это выглядело так после:

+$as_echo "$CC_FOR_BUILD" >&6; }
+
+case `pwd` in
+  *\ * | *\    *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+macro_version='2.4.2'
+macro_revision='1.3337'
+
+ltmain="$ac_aux_dir/ltmain.sh"

Используя vim, sed или awk. Возможно, какой-то другой инструмент.

UPD: uniq не подходит, потому что в таком большом патче он может удалить не только строки, начинающиеся с символа плюс.

С помощью dos2unix (поскольку ваш файл содержит возвраты каретки) и awk:

dos2unix < ваш_файл \
| awk 'BEGIN{FS="\n"; RS=""}
       {
         s=1;
         for(i=1; i<=NF; i++){
           if($i=="+" && s<2){print $i; s++}
           if($i!="+")       {print $i; s=1}
         }
       }'

Я решил эту задачу, используя следующий метод. Я повторял эту команду %s/^+$\n^+$\n^+$\n^+$/+/g в редакторе Vim, пока шаблон больше не находился. Думаю, это не лучшее решение, но в некоторых местах в патче я понял, что мне стоит сохранить две строки вместо одной.

Сказав это, в комментариях к самому вопросу, я думаю, что Тед Лингмо дал совершенно правильный ответ на мой вопрос.

Ответ или решение

Чтобы решить проблему поиска и замены строк, содержащих определённый символ, и оставить только одну строку в большом файле с более чем 80,000 строк, вам могут помочь такие инструменты, как vim, sed или awk. Ниже представлены несколько методов, которые могут быть полезны для выполнения этой задачи.

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

awk — это мощный инструмент для обработки текста, который позволяет выполнять операции на основе шаблонов. Ниже приведен пример использования awk вместе с dos2unix для обработки файла с символом перевода строки (CR):

dos2unix your_file | awk 'BEGIN{FS="\n"; RS=""}
{
  s=1;
  for(i=1; i<=NF; i++){
    if($i=="+" && s<2){print $i; s++}
    if($i!="+")       {print $i; s=1}
  }
}'

Объяснение:

  • dos2unix your_file — переводит файл из формата DOS в Unix, убирая символы перевода строки.
  • awk 'BEGIN{FS="\n"; RS=""} — настраивает awk на работу с пустыми строками как с разделителями записей.
  • Цикл for анализирует каждую строку в блоках. Если встречается строка с символом +, она печатается только один раз. Если встречается строка, не содержащая +, она печатается, и счётчик сбрасывается.

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

sed — это потоковый редактор, который может использоваться для манипуляций с текстом. Для выполнения подобной задачи можно использовать следующую команду:

sed -E ':a;N;$!ba;s/\n+\+/\n+/g;s/\n+/\\n/g;P;D' your_file | sed '/^+\s*$/d'

Объяснение:

  1. :a;N;$!ba; — приводит к тому, что sed считывает весь файл в память.
  2. s/\n+\+/\n+/g; — заменяет множественные строки с + на одну строку.
  3. s/\n+/\\n/g; — гарантирует, что строки с + не будут дублироваться.
  4. P;D — печатает строку и удаляет первую; это позволяет продолжить обработку оставшихся строк.
  5. Вторая команда sed '/^+\s*$/d' удаляет оставшиеся пустые строки.

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

Вы также можете воспользоваться vim для выполнения данной задачи. Чтобы заменить множественные строки + на одну, выполните следующие шаги:

  1. Откройте файл в vim:

    vim your_file
  2. Введите команду поиска и замены:

    :%s/\n\+\+/\\n/g

    Эта команда заменит все последовательные строки + на одну.

Итоги

Каждый из представленных методов имеет свои преимущества и недостатки. Выбор подхода зависит от вашей специфической задачи и предпочтений при работе с инструментами командной строки. Если вы хотите сохранить контроль над процессом, используйте vim. Для автоматизации задачи подойдёт awk или sed.

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

Оцените материал
Добавить комментарий

Капча загружается...