Home > Software design >  How to loop through two files (one text file, one json file) simultaneously in Bash?
How to loop through two files (one text file, one json file) simultaneously in Bash?

Time:01-14

I am a bit struggling writing a bash script. So I got some output in few files, and I have to define a new variable. However I need to use 2 files, and one is a normal text file, the other one is a JSON one:

file.txt

abcd
fghi
jklm

file.json

{
   "test0": "000",
   "test1": "011",
   "test2": "022"
}
{
   "test0": "100",
   "test1": "111",
   "test2": "122"
}
{
   "test0": "200",
   "test1": "211",
   "test2": "222"
}

I need to define a new variable this way:

final='{"example":"$file.txt-output","tags":"$file.json-output"}'

I can't find a way for the script to run each loop simultaneously, the file.txt output get send first.

I have tried a few ways just for testing, but still getting the same, eg.:

paste -- ~/file.txt ~/file.json | while read -r input1 input2
do
    echo "$input1 =  $input2"
done

Here is what I get:

"abcd" = {
"fghi" = "test0":
"jklm" = "test1":
} =
{ =
"test0": "100",
"test1": "111",
"test2": "122",
}

The "final" variable should look like that:

final='{"example":"abcd","tags":{ "test0": "000", "test1": "011", "test2": "022" }'
final='{"example":"fghi","tags":{ "test0": "100", "test1": "111", "test2": "122" }'
....

The JSON file looks like that, there is no "," and it's not an array. Any help would be much appreciated!

CodePudding user response:

jq -cs --rawfile texts file.txt '
  [$texts | split("\n")[] | select(. != "")] as $nonempty_text
  | [$nonempty_text, .]       # array with first all text lines, then all JSON 
  | transpose[]               # zip that array into (text, json) pairs
  | select(.[0] != null and .[1] != null) # ignore if we do not have both items
  | {"example": .[0], "tags": .[1]}       # otherwise emit output
' <file.json

...emits as output...

{"example":"abcd","tags":{"test0":"000","test1":"1111","test2":"2222"}}
{"example":"fghi","tags":{"test0":"100","test1":"111","test2":"122"}}

As this is one line per item, a standard while IFS= read -r final; do loop will handle it properly.

  • Related