Printing a recursive array - json

can someone help me print the "text" value from this json decoded array?
i did echo $obj["text"] and i get a blank :(
ah, i did the var_dump ; it says its an array of 20 elements inside an array of 1 element :-)
so after editing the code 42 times i have come to the solution only because the awesome Fangel helped that to print text the following line needs to be placed:
echo $obj[0]["text"];
$obj=[
{
"created_at":"Mon Sep 03 05:00:30 +0000 2012",
"id":242487207418544128,
"id_str":"242487207418544128",
"text":"Clint, come to the Democratic Convention. We'll get you a coherent speech to read - and we'll even help you comb your hair.",
"source":"web",
"truncated":false,
"in_reply_to_status_id":null,
"in_reply_to_status_id_str":null,
"in_reply_to_user_id":null,
"in_reply_to_user_id_str":null,
"in_reply_to_screen_name":null,
"user":{
"id":15376626,
"id_str":"15376626",
"name":"BarrackObama",
"screen_name":"BarrackObama",
"location":"Washington, D.C.",
"url":null,
"description":"President of the United States of America",
"protected":false,
"followers_count":94289,
"friends_count":1,
"listed_count":577,
"created_at":"Thu Jul 10 12:05:37 +0000 2008",
"favourites_count":0,
"utc_offset":-18000,
"time_zone":"Quito",
"geo_enabled":false,
"verified":false,
"statuses_count":106,
"lang":"en",
"contributors_enabled":false,
"is_translator":false,
"profile_background_color":"E6EB6F",
"profile_background_image_url":"http://a0.twimg.com/profile_background_images/76798997/PresidentialSeal.jpg",
"profile_background_image_url_https":"https://si0.twimg.com/profile_background_images/76798997/PresidentialSeal.jpg",
"profile_background_tile":false,
"profile_image_url":"http://a0.twimg.com/profile_images/56441335/so_normal.jpg",
"profile_image_url_https":"https://si0.twimg.com/profile_images/56441335/so_normal.jpg",
"profile_link_color":"0FA7FF",
"profile_sidebar_border_color":"EAFF08",
"profile_sidebar_fill_color":"171CA6",
"profile_text_color":"E69407",
"profile_use_background_image":true,
"default_profile":false,
"default_profile_image":false,
"following":null,
"follow_request_sent":null,
"notifications":null
},
"geo":null,
"coordinates":null,
"place":null,
"contributors":null,
"retweet_count":110,
"entities":{
"hashtags":[
],
"urls":[
],
"user_mentions":[
]
},
"favorited":false,
"retweeted":false
}
]

http://php.net/manual/en/function.json-decode.php
assoc
When TRUE, returned objects will be converted into associative
arrays.
When you set second parameter as true, you should do echo $obj["text"]; instead of $obj->text; because, as it says in manual, second parameter, when true, force json_decode return associative arrays even if it is an object in JSON.
As far as I can see, you have an array of objects in your JSON. So after json decode you should have an array of objects also. Just use foreach loop to go through array and print text of all items:
foreach($obj as $item) {
echo $item->text + "<br/>";
}
or like this for associative arrays(if second param of json_decode is true):
foreach($obj as $item) {
echo $item["text"] + "<br/>";
}

This is the way to print it:echo $obj[0]["text"];

Related

select array by any element exactly matched to specified value

Anyone know to how to implement this?
I have an array which has a nested array, say tagNames, I want to select all item which tagNames contains "auto-test" exactly, not "auto-test2".
{
"servers":[
{"id":1, "tagNames": ["auto-test", "xxx"]},
{"id":2, "tagNames": ["auto-test2", "xxxx"]}
]
}
So far, I am using
echo '{"servers":[{"id":1,"tagNames":["auto-test","xxx"]},{"id":2,"tagNames":["auto-test2","xxxx"]}]}' |\
jq '[ .servers[] | select(.tagNames | contains(["auto-test"])) ]'
I got two records, but I just want the first one.
[
{
"id": 1,
"tagNames": [
"auto-test",
"xxx"
]
},
{
"id": 2,
"tagNames": [
"auto-test2",
"xxxx"
]
}
]
So I want this:
[
{
"id": 1,
"tagNames": [
"auto-test",
"xxx"
]
}
]
Any idea?
You shouldn't use contains/1 as it will not work the way you might expect it, particularly if you're dealing with strings. It will recursively check if all parts are contained. So not only will it check if the string is contained in the array, but if the string is also a substring.
You'll want to write out your conditions checking any and all tags against your criteria.
[.servers[] | select(any(.tagNames[]; . == "auto-test") and all(.tagNames[]; . != "auto-test2"))]
One way would be to use index/1, e.g.
.servers[]
| select( .tagNames | index("auto-test"))
This produces:
{"id":1,"tagNames":["auto-test","xxx"]}
If you want that wrapped in an array, you could (for example) wrap the filter above in square brackets.
Another solution is to use the idiom: first(select(_)):
jq '.servers[] | first(select(.tagNames[]=="auto-test"))' file
If the first is omitted, then the same item in the servers array might be emitted more than once.

How do I parse this supposedly JSON format

I have a huge file with data in the below format. (It's the response from an API call I made to one of Twitter's APIs). I want to extract the value of the field "followers_count" from it. Ordinarily, I would do this with jq with the following command : cat | jq -r '.followers_count'
But this contains special characters so jq cannot handle it. Can someone help by telling me how do I convert it in JSON (e.g. using a shell script) or alternatively how to get the followers_count field without conversion? If this format has a specific name, I would be interested to know about it.
Thanks.
SAMPLE LINE IN FILE:
b'[{"id":2361407554,"id_str":"2361407554","name":"hakimo ait","screen_name":"hakimo_ait","location":"","description":"","url":null,"entities":{"description":{"urls":[]}},"protected":false,"followers_count":0,"friends_count":6,"listed_count":0,"created_at":"Sun Feb 23 19:08:04 +0000 2014","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":1,"lang":"fr","status":{"created_at":"Sun Feb 23 19:09:21 +0000 2014","id":437665498961293312,"id_str":"437665498961293312","text":"c.ronaldo","truncated":false,"entities":{"hashtags":[],"symbols":[],"user_mentions":[],"urls":[]},"source":"\u003ca href=\"https:\/\/mobile.twitter.com\" rel=\"nofollow\"\u003eMobile Web (M2)\u003c\/a\u003e","in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"favorited":false,"retweeted":false,"lang":"es"},"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_image_url_https":"https:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_tile":false,"profile_image_url":"http:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_image_url_https":"https:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_link_color":"1DA1F2","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":true,"default_profile_image":true,"following":false,"follow_request_sent":false,"notifications":false,"translator_type":"none"}]'
This is not the valid JSON, if you want to grab some certain part from this response, you can dump this result in file and then iterate over it and get the text you want to grab.
otherwise, if response will be in JSON, it will be easily parse through jq library, you can also dump this record in file, convert it into json and then parse it !
there are multiple ways 'grep,awk,sed' ..... you can go for it !
remove 'b from beginning and ' from bottom,it will become valid JSON !
Well i have removed the b' from beginning and ' from the bottom ! and look it is a valid JSON, now we can easily use jq with it like this !
i am doing it with my file....
jq -r '.accounts|keys[]' ../saadaccounts.json | while read key ;
do
DATA="$(jq ".accounts [$key]" ../saadaccounts.json )"
FNAME=$( echo $DATA | jq -r '.first_name' )
LNAME=$( echo $DATA | jq -r '.Last_name' )
done
*** YOUR JSON FILE ***
[
{
"id":2361393867,
"id_str":"2361393867",
"name":"graam a7bab",
"screen_name":"bedoo691",
"location":"",
"description":"\u0627\u0633\u062a\u063a\u0641\u0631\u0627\u0644\u0644\u0647 \u0648\u0627\u062a\u0648\u0628 \u0627\u0644\u064a\u0647\u0647 ..!*",
"url":null,
"entities":{
"description":{
"urls":[
]
}
},
"protected":false,
"followers_count":1,
"friends_count":6,
"listed_count":0,
"created_at":"Sun Feb 23 19:03:21 +0000 2014",
"favourites_count":1,
"utc_offset":null,
"time_zone":null,
"geo_enabled":false,
"verified":false,
"statuses_count":7,
"lang":"ar",
"status":{
"created_at":"Tue Mar 04 16:07:44 +0000 2014",
"id":440881284383256576,
"id_str":"440881284383256576",
"text":"#Naif8989",
"truncated":false,
"entities":{
"hashtags":[
],
"symbols":[
],
"user_mentions":[
{
"screen_name":"Naif8989",
"name":"\u200f naif alharbi",
"id":540343286,
"id_str":"540343286",
"indices":[
0,
9
]
}
],
"urls":[
]
},
"source":"\u003ca href=\"http:\/\/twitter.com\/download\/android\" rel=\"nofollow\"\u003eTwitter for Android\u003c\/a\u003e",
"in_reply_to_status_id":437675858485321728,
"in_reply_to_status_id_str":"437675858485321728",
"in_reply_to_user_id":2361393867,
"in_reply_to_user_id_str":"2361393867",
"in_reply_to_screen_name":"bedoo691",
"geo":null,
"coordinates":null,
"place":null,
"contributors":null,
"is_quote_status":false,
"retweet_count":0,
"favorite_count":0,
"favorited":false,
"retweeted":false,
"lang":"und"
},
"contributors_enabled":false,
"is_translator":false,
"is_translation_enabled":false,
"profile_background_color":"C0DEED",
"profile_background_image_url":"http:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png",
"profile_background_image_url_https":"https:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png",
"profile_background_tile":false,
"profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/437664693373911040\/ydODsIeh_normal.jpeg",
"profile_image_url_https":"https:\/\/pbs.twimg.com\/profile_images\/437664693373911040\/ydODsIeh_normal.jpeg",
"profile_link_color":"1DA1F2",
"profile_sidebar_border_color":"C0DEED",
"profile_sidebar_fill_color":"DDEEF6",
"profile_text_color":"333333",
"profile_use_background_image":true,
"has_extended_profile":false,
"default_profile":true,
"default_profile_image":false,
"following":false,
"follow_request_sent":false,
"notifications":false,
"translator_type":"none"
}
]

Need to get all key value pairs from a JSON containing a specific character '/'

I have a specific json content for which I need to get all keys which contains the character / in their values.
JSON
{ "dig": "sha256:d2aae00e4bc6424d8a6ae7639d41cfff8c5aa56fc6f573e64552a62f35b6293e",
"name": "example",
"binding": {
"wf.example.input1": "/path/to/file1",
"wf.example.input2": "hello",
"wf.example.input3":
["/path/to/file3",
"/path/to/file4"],
"wf.example.input4": 44
}
}
I know I can get all the keys containing file path or array of file paths using query jq 'paths(type == "string" and contains("/"))'. This would give me an output like:
[ "binding", "wf.example.input1" ]
[ "binding", "wf.example.input3", 0]
[ "binding", "wf.example.input3", 1 ]
Now that i have all the elements that contains some file paths as their values, is there a way to fetch both key and value for the same and then store them as another JSON? For example, in JSON mentioned for this question, I need to get the output as another JSON containing all the matched paths. My output JSON should look something like below.
{ "binding":
{ "wf.example.input1": "/path/to/file1",
"wf.example.input3": [ "/path/to/file3", "/path/to/file4" ]
}
}
The following jq filter will produce the desired output if given input that is very similar to the example, but it is far from robust and glosses over some details that are unclear from the problem description. However, it should be easy enough to modify the filter in accordance with more precise specifications:
. as $in
| reduce paths(type == "string" and test("/")) as $path ({};
($in|getpath($path)) as $x
| if ($path[-1]|type) == "string"
then .[$path[-1]] = $x
else .[$path[-2]|tostring] += [$x]
end )
| {binding: .}
Output:
{
"binding": {
"wf.example.input1": "/path/to/file1",
"wf.example.input3": [
"/path/to/file3",
"/path/to/file4"
]
}
}

JSON parsing error, Expecting 'EOF', '}', ',', ']'

I try to find out why my JSON is not legal.
I use this site: http://jsonlint.com/
The first example which is good is:
{
"data": 1290,
"value": "a"
}
The second which is not good is:
{
"data": 1290,
"value": "a"
}
I dont understand why the second one does not work. Its the same as the first one.
EDIT
I found this sings at the end of the string.
How to remove them using PHP? the string source is from php.
There might be some additional output after you output your json. Try trimming output and terminating further execution.
$json = array('data' => 1290, 'value' => 'a');
echo json_encode($json);
die();

Looping through JSON data and printing out a field using Perl (Not a HASH ref)

I need to loop through several jsons and print out index 1 of each...
I start with a generated string containing my JSON data. I then decode the string and dump it to show exactly what I'm working with:
my $decoded = decode_json $string
print Dumper $string
This results in the following output:
$VAR1 = [
{
'hdr' => [
1,
'acknowledged',
'',
'/home/clanier/dev/test/sds-test/data/JPLIDR2015169.64575',
'2015/271-19:10:39.0101355',
'2015/271-19:10:39.2599252',
''
]
},
{
'hdr' => [
2,
'acknowledged',
'',
'/home/clanier/dev/test/sds-test/data/JPLIDR2015169.64575',
'2015/271-19:10:39.3928414',
'2015/271-19:10:39.6397269',
''
]
},
{
'hdr' => [
3,
'acknowledged',
'',
'/home/clanier/dev/test/sds-test/data/JPLIDR2015169.64575',
'2015/271-19:10:39.7726375',
'2015/271-19:10:40.0162758',
''
]
}
];
Now I try to loop through this and print the word acknowledged for each one:
foreach my $hdr ( $decoded->{hdr} ) {
print $hdr->[1];
}
I looked to this solution for help, but it appears I cannot even get as far as the original poster, due to "Not a HASH reference" errors. I was able to print a specific one previously, but I need to loop through and print all of them. This was the code for that: print $$decoded[0]->{'hdr'}->[1];
$decoded is an array reference, not a hash reference. You can't dereference it as a hash: ->{.
You can dereference it as an array, though:
for my $hdr (#$decoded) {
print $hdr->{hdr}[1];
}
See perlreftut
for more information about references in Perl.