Это будет работать для вашего формата данных (т.е. не для возможного полного синтаксиса JSON) с использованием любого awk в любой оболочке на каждом поле UNIX:
$ cat tst.awk
{ rec = rec $0 }
END {
gsub(/^[ \t]*[{][ \t]*|[ \t]*[}][ \t]*$/,"",rec)
while ( match(rec,/"[^"]+"[ \t]*:[ \t]]*("[^"]*"|[^,]*)/) ) {
key = val = substr(rec,RSTART+1,RLENGTH-1)
sub(/".*/,"",key)
sub(/[^"]*"[ \t]]*:[ \t]*/,"",val)
f[key] = val
rec = substr(rec,RSTART+RLENGTH)
}
print f[k]
}
$ echo '{"version":1,"name":"2","tag":"3"}' | awk -v k=tag -f tst.awk
"3"
$ cat file
{
"version": 1,
"tag": "3",
"name" :"2"
}
$ awk -v k=tag -f tst.awk file
"3"
Вы можете легко вывести любое значение, которое вам нравится:
$ awk -v k=name -f tst.awk file
"2"
$ awk -v k=version -f tst.awk file
1
, и было бы тривиально изменить вывод нескольких значений в любом порядке, или вывести значение только одной клавиши, если оно находится в диапазоне или основано на отношениях между другие значения ключей, et c., et c. Например:
$ cat tst.awk
{ rec = rec $0 }
END {
split(keys,ks,/,/)
gsub(/^[ \t]*[{][ \t]*|[ \t]*[}][ \t]*$/,"",rec)
while ( match(rec,/"[^"]+"[ \t]*:[ \t]*("[^"]*"|[^,]*)/) ) {
key = val = substr(rec,RSTART+1,RLENGTH-1)
sub(/".*/,"",key)
sub(/[^"]*"[ \t]*:[ \t]*/,"",val)
f[key] = val
rec = substr(rec,RSTART+RLENGTH)
}
if ( (f["version"] > 0) && (f["name"] != f["tag"]) ) {
for (i=1; i in ks; i++) {
k = ks[i]
print k, f[k]
}
}
}
$ awk -v keys=tag,version,name -f tst.awk file
tag "3"
version 1
name "2"
Было бы тривиально обрезать кавычки вокруг значений, если они вам не нужны, просто добавив gsub(/^"|"$/,"",val)
в l oop прямо над f[key] = val
.