Arhn - архитектура программирования

найти и заменить строку ИЛИ добавить в конец файла

Можно ли найти и заменить строку в файле ИЛИ добавить строку в конец, если ее там нет?

Я знаю, что могу использовать это, чтобы найти и заменить:

sed -i -e "s/^SEARCH/LINE 1\nLINE 2/" file

Я знаю, что могу дополнить файл следующим образом:

cat << EOF | tee -i file1 file2
LINE 1
LINE 2
EOF

Можно ли это как-то совместить. Поэтому, если /^SEARCH.*$/ соответствует, замените его, если нет, добавьте замену в конец файла.

Обновить с помощью лучшего примера ввода/вывода:

Например, если бы у меня был этот входной файл testfile:

Alpha
Bravo
Charlie

Допустим, я хотел найти и заменить Bravo на Bravo=bingo, ИЛИ добавить Bravo=bingo, если Bravo там нет, ожидаемый результат:

Alpha
Bravo=bingo
Charlie

Это связано с тем, что в файле существует Bravo, поэтому он заменяется.

Допустим, я хотел найти и заменить Delta на Delta=bingo, ИЛИ добавить Delta=bingo, если Delta там нет, ожидаемый результат:

Alpha
Bravo
Charlie
Delta=bingo

Это связано с тем, что Delta отсутствует в файле, поэтому он добавляется.

03.02.2019

  • Я не застрял на sed. Разве SO/SE не является лучшим способом что-то сделать? Способ, который вы показали, работает, и он особенно полезен для вставки чего-либо с несколькими строками, но вы говорите, что это лучший способ сделать это, если вам не нужно вставлять несколько строк? Если да, то я отделюсь. Причина, по которой я хочу снова открыть вопрос, состоит в том, чтобы посмотреть, есть ли лучший способ сделать это, когда вам не нужно вставлять что-то с несколькими строками. 03.02.2019
  • Да, это именно то, о чем я говорю, так как это ясно, просто, портативно, эффективно, надежно и легко расширяется. idk, что означает SO/SE, кстати, и не смог найти его определение с помощью поиска в Google. 04.02.2019
  • Ваш пояснительный текст не соответствует вашим образцам выходных данных. Вы говорите, что хотите заменить ^SEARCH=.*$, но это не соответствует вашему примеру Bravo. Вы говорите, что хотите добавить Delta=bingo, но на самом деле добавляете Delta. 05.02.2019
  • @jhnc Ой. Извините за опечатки. Я исправил. 05.02.2019

Ответы:


1

awk однострочный:

awk 'gsub(/^SEARCH/,"LINE 1\nLINE 2"){s=1}END{if(!s)print "LINE 1\nLINE 2"}1' file

Это не заменяет на месте, если вы хотите изменить на месте:

awk 'gsub(/^SEARCH/,"LINE 1\nLINE 2"){s=1}END{if(!s)print "LINE 1\nLINE 2"}1' file | tee file

Не забудьте избежать оригинала и замены, если они содержат regex символов, это проще, чем изменить метод match/substr, когда тексты не длинные.

03.02.2019
  • Таким образом, это в основном пытается выполнить замену, и если это сработает, оно установит переменную, а если нет, то в конце напечатает эту строку? 03.02.2019
  • @IMTheNachoMan Верно. 03.02.2019
  • @IMTheNachoMan Независимо от того, работает замена или нет, строки будут напечатаны. переменная s предназначена для определения, наконец, добавить или нет. 03.02.2019
  • Это не удастся, учитывая различные возможные символы в исходном тексте и тексте замены. Эту проблему необходимо решить с помощью операций со строками, а не с помощью регулярных выражений и текста с поддержкой обратной ссылки. 03.02.2019
  • @IMTheNachoMan Проверьте, что упомянул Эд, если у вас есть такие сценарии, будьте осторожны и не забывайте избегать (проще, чем изменить на соответствие и подстроку и т. Д., Если текст невелик). 03.02.2019
  • @EdMorton Спасибо, что упомянули об этом. 03.02.2019

  • 2

    Запасная часть точно такая же, как на https://stackoverflow.com/a/54504046/1745001, но вот она упрощено для этого конкретного случая использования, а настройка добавления, если он не найден, выполняется просто путем установки флага, если он найден, и печати в КОНЦЕ, если этот флаг не установлен:

    awk 'BEGIN{new="LINE 1\nLINE 2"} /^SEARCH/{$0=new; f=1} {print} END{if (!f) print new}' file
    

    Опять же, вышеприведенное использует строки для замены, и поэтому будет работать для любых символов, /^SEARCH/ - это регулярное выражение, поскольку у вас нет метасимволов регулярного выражения, но если бы вы это сделали, вы бы изменили это на index($0,"SEARCH")==1 или подобное, чтобы сделать строку, а не чем соответствие регулярному выражению.

    03.02.2019

    3

    Однострочник GNU sed:

    sed -i 's/^SEARCH/LINE 1\nLINE 2/;ts;bt;:s;h;:t;${x;/./!{x;s/$/\nLINE 1\nLINE 2/;be};x};:e' file
    
    03.02.2019
  • Не могли бы вы объяснить, что все это делает? Я не могу следовать/понимать. 03.02.2019
  • @IMTheNachoMan Не могли бы вы найти и прочитать документ, сначала попытаться понять его самостоятельно? Если после этого у вас возникнут какие-либо вопросы, вы можете задать их еще раз. (t/b — переходы, а :s/:t/:e — якоря) 03.02.2019

  • 4

    Не знаю об одной команде sed, но вы можете просто сделать sed резервную копию файла, а затем проверить разницу. Если нет разницы, добавьте в конец файла:

    sed -i.bak -e 's/^SEARCH/LINE 1\nLINE 2/' file
    diff file file.bak > /dev/null
    if [ $? -eq 0 ]; then
        sed -i -e '$aLINE 1\nLINE 2' file
    fi
    
    03.02.2019
  • Эта последняя строка sed будет рассматривать $aLINE как переменную оболочки, которая расширяется до нуля. Всегда используйте одинарные кавычки вокруг строк и скриптов, если только у вас нет особой НЕОБХОДИМОСТИ в использовании двойных кавычек (например, чтобы представить скрипт/строку в оболочке для расширения переменных) и полностью понимать последствия и последствия. Он потерпит неудачу по-разному, учитывая различные значения SEARCH и каждой LINE, и вызов нескольких инструментов для файла, очевидно, является очень неэффективным подходом (например, почему первый sed + diff вместо одного grep для SEARCH?). 04.02.2019
  • Спасибо, @ЭдМортон. Починил это. 05.02.2019
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..