В одном из моих 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. Может ли кто-нибудь здесь помочь?
Предположим, что строка, которую вы хотите извлечь, стоит в одной и той же позиции в каждом файле, вы можете использовать команды head
, tail
и cut
с помощью труб.
Например:
$ head -6 file.json | tail -1 | cut -b 121-129
db1.table
А вот пример скрипта, устанавливающего вывод в переменную:
#/bin/bash!
v1=$(head -6 file.json | tail -1 | cut -b 121-130)
echo "$v1"
вывод скрипта будет db1.table4
, что является значением V1
переменной.
подробнее об этих командах можно прочитать здесь:
конечно, вы можете использовать эти команды для извлечения любой другой строки из файла.
Обычно вам следует избегать использования общих инструментов анализа текста для структурированных данных. Поскольку у вас есть файл 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"
]
Отсюда у вас больше нет структурированных данных, и вам нужно прибегнуть к более грубым методам. Я не знаю, как вы хотите идентифицировать свою целевую строку, вы этого не объяснили. Итак, в зависимости от того, что вы действительно хотите, вы можете:
Пропустить строки, начинающиеся с [
или ]
, а затем вывести второе слово из оставшихся строк:
$ jq '. "$ quer". "args" [0] ["args"]' file.json | awk '/ ^ [^] [] / {print $ 2}'
db1.table1
Вывести второе слово второй строки
$ jq '. "$ quer" . "args" [0] ["args"] 'file.json | awk 'NR == 2 {print $ 2}'
db1.table1
Вывести самый длинный отрезок без пробелов после строки "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
Посмотрите на 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)