0

EDIT I have a piece of a code, which printed out expected info and hindered me debugging. Then I was wondering if there is a way to 'use echo but do not print' or there was something in my code. Below was my original question.

Original question

I know my request maybe weird since many people are worried about 'not printing' and I can't get an answer since all my search are spammed by that. Eg, I just want the following code to be executed quietly without print {another_thing}. I am using GNU bash, version 4.3.48, Ubuntu 16.04 LTS.

for sth in $(echo $another_thing |jq -r 'keys[]');do
    count=$(echo $another_thing |jq -r ".[\"${sth}\"].somekey |length")
    echo ${count}
done

I only want to see:

1 .

2 .

3 .

.. instead of .

some long string .

some long string .

1 .

some long string .

some long string .

2 .

...

example of another_thing:

{
    "test": {
        "domain": "abc.com",
        "regions": [{
            "geo": "\"CountryCode\":\"AA\"",
            "server": "1.2.33.4",
            "action": "proxy",
            "proxy": "as-test.abc.com"
        }, {
            "geo": "\"ContinentCode\":\"BB\"",
            "server": "1.2.3.4",
            "action": "proxy",
            "proxy": "test.abc.com"
        }]
    },
    "sample": {
        "domain": "bbb.com",
        "regions": [{
            "geo": "\"CountryCode\":\"AA\"",
            "server": "4.5.6.7",
            "action": "redirect",
            "redirect": "abc.com"
        }, {
            "geo": "\"ContinentCode\":\"BB\"",
            "server": "6.7.8.9",
            "action": "proxy",
            "proxy": "sample.bbb.com"
        }]
    }
}

What I want to do is to get the info region info under each element and then do other stuff. A more detailed version of code inside 'for' loop

index=0
count=$(echo $another_thing |jq -r ".[\"${sth}\"].regions |length")
while [ $index -lt $count ]; do
    geo=$(echo $another_thing |jq -r ".[\"${sth}\"].regions[${index}].geo")
    geoid=$(echo ${geo} |sed 's|"||g' |awk -F: '{print $2}' |tr [:upper:] [:lower:])
    server=$(echo $another_thing |jq -r ".[\"${sth}\"].regions[${index}].server")
    some_function ${varible_1} ${varible_2} $server $geo $geoid
    index=$(expr $index + 1)
done

closed as unclear what you're asking by Kusalananda, Thomas, JigglyNaga, user88036, RalfFriedl Oct 9 '18 at 13:13

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • I'm not sure what long string that would output apart from the lengths, at least unless you get any errors from jq. Can you add a sample of some data with the problem? (Just a small snippet is enough, it just needs to make the issue clear.) – ilkkachu Oct 9 '18 at 5:10
  • @ilkkachu just added in the question, is it what you are looking for? – tikael Oct 9 '18 at 5:27
  • @Vlastimil did you mean the title? I just changed to lowercase – tikael Oct 9 '18 at 5:27
  • I'm unsure of what it is you are trying to do with the code. You are passing a variable into jq insecurely. Do you want to get the length of e.g. the .domain for each object? You can get that with jq -r '.[].domain|length'. Also, it's unclear what text it is you want to not display. – Kusalananda Oct 9 '18 at 5:47
  • 1
    @tikael ,do check if some_function is doing some echos internally - that is the only source of any output seeping in , with the current information we have – amisax Oct 9 '18 at 6:03
1

I'm honestly not quite sure where you get the output from that you say you're getting, but the shell code that you are using is overly complex, calling four external utilities in each iteration (apart from what some_function may be doing).

Here's an alternative implementation (assuming the JSON data is in file.json):

#!/bin/bash

jq -r '.[].regions[]|[.geo, .server]|@tsv' <file.json |
while IFS=$'\t' read geo server; do
    geoid=${geo#*:}
    geoid=${geoid//\"/}
    some_function "$variable1" "$variable2" "$server" "$geo" "$geoid"
done

For the given data, the jq call would generate the following output:

"CountryCode":"AA"      1.2.33.4
"ContinentCode":"BB"    1.2.3.4
"CountryCode":"AA"      4.5.6.7
"ContinentCode":"BB"    6.7.8.9

This is a tab-delimited text which the shell loop is then reading into geo and server.

The geoid is simply parsed out of $geo by first deleting the stuff before the : and then removing any double quotes from the remaining value. This is done by using two variable substitutions (of which the second one needs a shell like bash).

The some_function is then called.

To debug your output issue, let us know what some_function does.

  • I guess I need to revise my code...thanks for pointing out my code is to complex. – tikael Oct 9 '18 at 6:56

Not the answer you're looking for? Browse other questions tagged or ask your own question.