0

I am trying to write a bash script that generates uuids and writes that to a file, in a json array format. I have written a simple code that generates the id and writes to a file but the issues i am running into are;

here is my own implementation

function uud {
     for ((i=1;i<=$1;i++));
     do 
         echo "\`uuidgen\`", >> $file
     done 
 }

 for file in file1.json file2.json;
 do 
     $( uud $1)
done
  1. I am having issues with converting the ids into strings.
  2. Converting the results to arrays.

Currently my solution prints the ids into the file in this format

caca8fef-42d6-4b21-9d6b-0e40d348bd53,
e6e12fb5-4304-4ba9-b895-931bb4b58fbf,
df699ecd-d887-413e-8383-2a98ac2fa22f,

and this is what i want to acheive, How can I go about getting this result?

[
"caca8fef-42d6-4b21-9d6b-0e40d348bd53",
"e6e12fb5-4304-4ba9-b895-931bb4b58fbf",
"df699ecd-d887-413e-8383-2a98ac2fa22f"
]
0

3 Answers 3

3

Use jq to generate the JSON.

uud () {
    for ((i=0; i< $1; i++)); do
        uuidgen
    done
}

for file in file1.json file2.json; do
    uud 5 | jq -Rs 'rtrimstr("\n") | split("\n")' > "$file"
done

-Rs reads the entire input into a single JSON string, which you then split (after removing the trailing newline) on newlines to produce the desired array.


One blogger suggests using two jq processes, which is more expensive but arguably simpler:

for file in file1.json file2.json; do
   uud | jq -R . | jq -s . > "$file"
done
Sign up to request clarification or add additional context in comments.

5 Comments

End up with a trailing empty string in your list from the split() treating the terminating newline from the last entry as a split point. Maybe add a [:-1]?
Thanks; I've opted to strip the trailing newline before splitting.
(An alternative that I found while researching would be to use jq twice: jq -R . | jq -s .. I think a single process is still preferable, but the simplicity of the two separate commands is compelling.)
Single jq process, but not sure it is much easier to read: jq --null-input '$ARGS.positional' --args $(uud 5) > "$file"
Hm, ARGS.positional is newer, so I didn't think of that. I'm not crazy about the unquoted command substitution, but it should be safe assuming a standard value for IFS.
1

I have adjusted slightly your script, try it:

function uud {
    echo "[" > $file
    for ((i=1;i<$1;i++));
    do 
        echo \"$(uuidgen)\", >> $file
    done 
    echo \"$(uuidgen)\" >> $file           # last item in array without comma 
    echo "]" >> $file
 }

for file in file1.json file2.json;
do 
    $( uud $1)
done

Or execute it here and check the result.

4 Comments

$(uud $1), not uud "$1" on its own? Why would you want to tell the shell to read the uud function's stdout and run that stdout as a separate command?
For that matter, is there a good reason for making uud depend on a global file variable instead of having it write to stdout? Taking all the >$file and >>$file out of the function and just invoking it with uud >"$file" would be a lot more clear.
...the other thing is that the unquoted expansions you're doing are arguably safe with uuidgen but would be unsafe with other programs (things able to contain whitespace-surrounded wildcards in their output, f/e). Consider trying to make your code run shellcheck-clean to reduce the likelihood of folks adapting it to different use cases tripping over bugs.
My intention here was adjust his own solution as minimal as possible.
0

After you've run your existing loop...

#!/bin/sh
cat > ed1 <<EOF
%s/^/"/g
%s/$/"/g
$s/,//
1i
[
.
$a
]
.
wq
EOF

ed -s file < ed1

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.