Сравнение/проверка файла dot env

Если у вас есть несколько файлов .env в данном каталоге для определенных сред, например. dev.env, staging.env и prod.env, используя оболочку, можно ли проверить, что каждый файл имеет одинаковые ключи env var, игнорируя значения?

Например, для следующих файлов:

dev.env

KEY_1=DEV_VALUE_1
KEY_2=DEV_VALUE_2

staging.env

KEY_1=STAGING_VALUE_1
KEY_2=STAGING_VALUE_2

prod.env

KEY_1=PROD_VALUE_1
KEY_2=PROD_VALUE_2
KEY_3=PROD_VALUE_3

Может ли кто-нибудь предложить команду awk или аналогичную, которая вернет ненулевой код выхода из-за того, что prod.env содержит дополнительный ключ? Цель здесь состоит в том, чтобы проверить, что все файлы .env выровнены по ключам, которые они объявляют, в первую очередь в настройках CI.

Все файлы, кроме prod.env, всегда состоят из трех строк?

Cyrus 09.04.2022 22:57

Почему бы не использовать любой язык, который вы используете, с парсером dotenv?

chepner 09.04.2022 22:58

@ Сайрус нет, ожидается, что все файлы .env будут иметь одинаковое количество ключей. Наивным подходом может быть просто проверка того, что каждый файл имеет одинаковое количество строк, но это может быть проблемой, если ключ был по ошибке переименован в одном файле, а не в другом.

Luke Stoward 09.04.2022 23:03

@chepner эта проверка работоспособности будет происходить в настройках CI и не зависит от проекта. Я бы предпочел управлять этим в оболочке, если это возможно, прежде чем вернуться к языку, используемому данным проектом.

Luke Stoward 09.04.2022 23:05

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

chepner 09.04.2022 23:11

@chepner Я понимаю, что могу использовать язык по своему выбору, однако я надеялся, что смогу достичь своей цели с помощью утилиты GNU. Как вы сказали awk, вероятно, не лучший выбор.

Luke Stoward 09.04.2022 23:14

Все стандартные утилиты на десятки лет старше современных форматов файлов, и ни одна из них не подходит для написания парсеров. (Есть причина, по которой такие инструменты, как yacc, были созданы вместо простого повторного использования awk и др.)

chepner 09.04.2022 23:16
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
7
32
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Конечно, посчитайте файлы для каждого ключа и покажите несоответствия.

#! /usr/bin/awk -f

{
    keys[$1]++
}

END {
    for( key in keys ) {
        if( n == 0 ) {
            n = keys[key]
        }

        if( keys[key] != n ) {
            printf "%s appears in %d of %d files\n", \
            key, keys[key], n > "/dev/stderr"
        }
    }
}
$ awk -F= -f ./missing.awk *.env
KEY_3 appears in 1 of 3 files

Ах ха! Отлично, как раз то, что я пытался найти, спасибо, Джеймс!

Luke Stoward 09.04.2022 23:22

Я думал в том же направлении. Один из способов обойти это — сделать так, чтобы ключ появлялся несколько раз в одном файле.

glenn jackman 09.04.2022 23:23

@glennjackman, именно так. Я также предполагаю, что каждая строка содержит присваивание '=' переменной среды. Однако с дубликатами легко справляются. Ведите отдельный подсчет ключей для текущего файла и не добавляйте дубликаты к общему подсчету. Сбрасывать счетчик для каждого файла всякий раз, когда изменяется FILENAME.

James K. Lowden 09.04.2022 23:28

Это не работает для многострочных значений и комментариев, содержащих =. awk обрабатывает файл по одному линия за раз, а не по одной паре ключ-значение за раз.

chepner 09.04.2022 23:30

(Помимо этого, вы также можете установить FS в блоке BEGIN вместо того, чтобы требовать от вызывающей стороны использовать -F и -f при запуске awk.)

chepner 09.04.2022 23:31

Can anyone suggest an awk command or similar that would return a non-zero exit code due to prod.env containing an extra key?

Я бы использовал GNU AWK для этой задачи следующим образом

awk 'BEGIN{FS="=";PROCINFO["sorted_in"]="@ind_str_asc"}FNR==1{delete arr1}{arr1[$1]}ENDFILE{keys="";for(i in arr1){keys = keys FS i};arr2[keys];if(length(arr2)>1){exit(1)}}' *.env

Объяснение: я сообщаю GNU AWK, что разделителем полей является = и этот массив должен проходиться с отсортированными индексами. В начальной строке каждой строки я очищаю массив arr1, затем для каждой строки упоминаю ключ, являющийся значением 1-го столбца массива arr1, после обработки файла я создаю строку keys, объединяя ключи arr1 с помощью разделителя полей. Здесь важен порядок обхода, так как он обеспечивает, что 2 файла с одинаковыми ключами в разном порядке дадут одну и ту же строку. Затем я использую эту строку в качестве ключа arr2, и если в arr2 более 1 разных ключей, я выхожу с ненулевым кодом, как это предусмотрено требованиями.

(проверено в GNU Awk 5.0.1)

Вот версия, которая не только сообщит вам о неправильно выровненных ключах, но также покажет вам, каковы их значения и из какого файла .env:

 mawk 'BEGIN { FS=OFS="="
             __++ 
     } __~FNR {++____; _=FILENAME 
     }        {
             ___[$__]=___[$__]""_""FS""($NF)" | "
     } END { 
            _____=" %s only shows up at ::: %s\n"
        for(__ in ___) {

             _=___[__] 
             sub("[ ]*[|][ ]*$","",_)
             
             if(____!=gsub(FS,"&",_)) {
                   printf(_____,__,_) } } }' test*.env | lgp3

    KEY_3 only shows up at ::: testprod.env=PROD_VALUE_3

Другие вопросы по теме