Я согласен, что в этом случае jq предпочтительнее, чем awk (дополнительные комментарии приведены ниже).Если вы знаете, что json довольно напечатан (только одна запись в строке), вы можете использовать регулярное выражение, чтобы разбить строку на три части.
awk -v field="${3}" '
BEGIN {
IGNORECASE = 1
regex = sprintf("^([^\"]*\"%s\"[^:]*:[^\"]*\")([^\"]*)(\".*)$", field)
}
$0 ~ regex {
before = gensub(regex, "\\1", 1)
password = gensub(regex, "\\2", 1)
after = gensub(regex, "\\3", 1)
masked = gensub(/./, "X", "g", password)
printf("%s%s%s\n", before, masked, after)
next
} { print }' "${1}" > "${2}"
Сценарий awk, который я написал, соответствует только трем компонентам красивой печатной строки:
[^\"]*\"%s\"[^:]*:[^\"]*\"
соответствует строке ввода до точки с запятой.Имя поля должно быть в двойных кавычках. [^\"]*
: соответствует значению записи \".*
: соответствует конечной двойной кавычке поля и, возможно, запятым и другим полям.
Затем скрипт маскирует пароль, заменяя каждый символ на «X».Наконец, он печатает конечный результат и пропускает следующий блок.
Предостережения:
- JSON должен быть достаточно напечатан или иметь хотя бы одно поле пароля на строку
- Поле пароля должно быть первым полем строки
- Этот скрипт не поддерживает экранированные двойные кавычки внутри полей
- Этот скрипт работает только с gnu awk (или gawk)
Комментарий: я бы добавилс решением jq или, может быть, запечь jq в файл bash, если переносимость обязательна.