Как извлечь строку из файла json и поместить в переменную (Linux)

В одном из моих json-файлов file1.json] есть следующее: -

{
    "$quer": {
        "args": [
            {
                "args": [
                    "select\n      db1.table1 as tab1,\n      db1.table2 as tab2,\n      db1.table3 as tab3\n      from db1.table4 as tab4"
                ],
                "fn": "from-sql",
                "ns": "op"
            }
        ],
        "fn": "operators",
        "ns": "op"
    }
}

I хотите извлечь строку db1.table4 из этого json-файла и сохранить в переменной.

Я мало знаю о sed и awk. Может ли кто-нибудь здесь помочь?

0
задан 14 August 2021 в 15:10

3 ответа

  1. Предположим, что строка, которую вы хотите извлечь, стоит в одной и той же позиции в каждом файле, вы можете использовать команды head, tail и cut с помощью труб.

  2. Например:

    $ head -6 file.json | tail -1 | cut -b 121-129
    db1.table
    
  3. А вот пример скрипта, устанавливающего вывод в переменную:

#/bin/bash!

v1=$(head -6 file.json | tail -1 | cut -b 121-130)
echo "$v1"

вывод скрипта будет db1.table4, что является значением V1 переменной.

подробнее об этих командах можно прочитать здесь:

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

2
ответ дан 20 August 2021 в 10:26

Обычно вам следует избегать использования общих инструментов анализа текста для структурированных данных. Поскольку у вас есть файл json, безопаснее и проще использовать специальный парсер json. В вашем случае вам нужно извлечь значение первого элемента массива args , который сам является первым элементом массива верхнего уровня args , дочернего элемента верхнего уровня. hash $ quer :

$ jq '."$quer"."args"[0]["args"]' file.json
[
  "select\n      db1.table1 as tab1,\n      db1.table2 as tab2,\n      db1.table3 as tab3\n      from db1.table4 as tab4"
]

Отсюда у вас больше нет структурированных данных, и вам нужно прибегнуть к более грубым методам. Я не знаю, как вы хотите идентифицировать свою целевую строку, вы этого не объяснили. Итак, в зависимости от того, что вы действительно хотите, вы можете:

  1. Пропустить строки, начинающиеся с [ или ] , а затем вывести второе слово из оставшихся строк:

     $ jq '. "$ quer". "args" [0] ["args"]' file.json | awk '/ ^ [^] [] / {print $ 2}' 
    db1.table1 
     
  2. Вывести второе слово второй строки

     $ jq '. "$ quer" . "args" [0] ["args"] 'file.json | awk 'NR == 2 {print $ 2}' 
    db1.table1 
     
  3. Вывести самый длинный отрезок без пробелов после строки "select \ n :

     ​​$ jq '. "$ Quer". "Args" [0] ["args"]' file.json | grep -oP '"select \\ n \ s * \ K \ S *' 
    db1.table1 
     

Если вы объясните, как именно мы должны знать, какую строку извлекать, я мог бы дать вам более конкретный ответ.


Для завершения, в вашем конкретном примере , я подчеркиваю, что это не будет переносимым и почти наверняка выйдет из строя, если ваши входные данные изменятся каким-либо образом, вы можете использовать простые текстовые инструменты напрямую:

$ grep -oP '"select\\n\s*\K\S*' file.json 
db1.table1

$ awk '$1=="\"select\\n"{print $2}' file.json 
db1.table1

$ sed -nE 's/.*"select\\n\s*(\S+).*/\1/p' file.json 
db1.table1
1
ответ дан 20 August 2021 в 10:26

Посмотрите на jq процессор JSON командной строки, установите, например, с помощью:

sudo apt install jq

https://stedolan.github.io/jq/manual/

Строка, которая вам нужна, не является значением JSON, это часть значения JSON. Поэтому я предлагаю вам использовать jq для получения строки, которой вам нужно манипулировать, в переменную, например:

my_var=$(jq -r .[$quer].args[0].args[0] file1.json)

Это даст вам переменную, содержащую оператор SELECT:

select db1. table1 as tab1, db1.table2 as tab2, db1.table3 as tab3 from db1.table4 as tab4

Затем вам нужно будет использовать другие инструменты, такие как sed, awk, cut и т.д., чтобы получить нужную вам подстроку из этой переменной. Для вашего конкретного случая это сработает, но, конечно, может не сработать для другого оператора SELECT. Обрезание по разделителю пробелов и возврат 12-го значения:

my_table=$(echo $my_var | cut -d' ' ' -f12)

2
ответ дан 20 August 2021 в 10:26

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

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