Заменить значение в операторе «ключ :значение», но только при первом появлении ключа в файле

После текущего конца -состояния «JACK начинается, если интерфейс установлен на hw :PCH или hw :PCH,0, но у меня нет никаких динамиков, кроме моего экрана, который находится на HDMI моей видеокарты, так что я не уверен, что в этом есть смысл». Я:

  • Нашел какие-то ужасные старые наушники
  • подключил их к встроенному -разъему для наушников на моем компьютере
  • побежалa2jmidid -j default
  • установить интерфейс JACK наhw:PCH
  • Подсоединил различные соединения в JACK, следуя этому руководству
  • успешно записал несколько случайных шумов на (MIDI )клавиатуре
  • воспроизвел их через наушники.

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

5
27.02.2021, 02:24
5 ответов

Если файл длиннее, вот решение на основе awk-, которое обрабатывает его построчно -мудро:

awk '/^[[:space:]]+username/ && !u_chng{sub(/:.+$/,": toto"); u_chng=1}
     /^[[:space:]]+password/ && !p_chng{sub(/:.+$/,": totospw"); p_chng=1} 1' input.yml 

Каждая строка будет проверяться, начинается ли она с usernameили passwordсоответственно. Если это так, и связанные флаги u_chngи p_chngеще не установлены, он устанавливает значение после :на новое желаемое и устанавливает соответствующий флаг, чтобы любые дальнейшие вхождения этих ключевых слов игнорировались.

Результат:

spring:
  datasource:
    url: url
    username: toto
    password: totospw
api:
  security:
    username:foo
    password: foopwd

Обратите внимание: если вы используете реализацию awk, которая не понимает классы символов ([[:space:]]), измените

/^[[:space:]]+username/

-

/^[ \t]+username/
4
18.03.2021, 22:28

Если ваш файл достаточно мал и не помещается в памяти, вы можете попробовать прочитать его целиком как одну запись. Таким образом, sedпроизведет замену только в первый раз, когда увидит шаблон в "строке" записи ():

$ sed -Ez 's/(username:)[^\n]*/\1toto/; s/(password:)[^\n]*/\1totopsw/' file.yaml 
spring:
  datasource:
    url: url
    username:toto
    password:totopsw
api:
  security:
    username:foo
    password: foopwd

Чтобы внести изменения в исходный файл, просто добавьте-i:

sed -i -Ez 's/(username:)[^\n]*/\1toto/; s/(password:)[^\n]*/\1totopsw/' file.yaml 
4
18.03.2021, 22:28

Другая sedальтернатива:

sed '1,/username/{/username/ s/:.*/:toto/};
     1,/password/{/password/ s/:.*/:totopsw/}' infile

1,/regex/начать с первой строки вверх -до первой строки, совпавшей с заданнойregex(здесь usernameстрока ), изменить "имя пользователя"; делаем то же самое для части «пароль».

5
18.03.2021, 22:28

Сgnu awk

awk -F '^\\s+|:' '
  BEGIN {
    a["username"] = "toto"
    a["password"] = "totopsw"
  }
  ($2 in a) {
    sub(/:.*/, ": " a[$2])
    delete a[$2]
  };1
' file
  • установить разделитель полей в виде двоеточия или пробела
  • Инициализируйте массив a с ключевыми словами для поиска n соответствующих им замен.
  • после каждой успешной операции поиска -n -заменить, удалить ключ.
1
18.03.2021, 22:28

если скрипт bashдействителен, вы можете использовать командуsedquit:

#!/bin/bash

sed -E '
    # If we find an username
    /username/ {

        # make the sobstitution of the username
        s/^([[:space:]]*username:)/\1toto/g

        n # Take the next line with the password

        # Sobstitute the password
        s/^([[:space:]]*password:).*$/\1totopw/g

        q1 # Quit after the first match
    }
' test.yml > new_test.yml

# How many line we have taken
len_line=$(sed -n '$=' new_test.yml)

# write the other line
sed "1,${len_line}d" test.yml >> new_test.yml

# rename all the file
rm -f test.yml
mv new_test.yml test.yml
1
18.03.2021, 22:28

Теги

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