I have got a json file whose content is like below:
cat myjson.json
[
{"a":"1", "b":"c BEGIN END"},
{"a":"2", "b":"d BEGIN END"},
{"a":"3", "b":"e BEGIN END"},
{"a":"4", "b":"f BEGIN END"}
]
What I need to do is transform this file to something like below
cat myjson.json
[
{"a":"1", "b":"c BEGIN 12341 END"},
{"a":"2", "b":"d BEGIN 43234 END"},
{"a":"3", "b":"e BEGIN 53474 END"},
{"a":"4", "b":"f BEGIN 54236 END"}
]
That is, inserting a random number between BEGIN and END keywords and this random number have to be different for each line.
I tried constructing below command
awk '{$0=gensub(/BEGIN(.*?)END/, "BEGIN $RANDOM END", "g", $0)}1' myjson.json
but the result is like below:
awk '{$0=gensub(/BEGIN(.*?)END/, "BEGIN $RANDOM END", "g", $0)}1' myjson.json
[
{"a":"1", "b":"c BEGIN $RANDOM END"},
{"a":"2", "b":"d BEGIN $RANDOM END"},
{"a":"3", "b":"e BEGIN $RANDOM END"},
{"a":"4", "b":"f BEGIN $RANDOM END"}
]
Instead of generating random number, it printed $RANDOM as is. How can I overcome this?
PS: I cannot use any third party tools/libraries. I have to do it in bash and I can only use sed or awk because real file has a lot of lines and I have to do it very fast.
Thanks in advance.
CodePudding user response:
You may try this awk
:
awk '
function rnd() { # generates random num between 10K and 100K
return int(rand()*100000-1) 10000
}
BEGIN { srand() } # seed the random
{
print gensub(/(BEGIN)\s (END)/, "\\1 " rnd() " \\2", "1")
}' file.json
[
{"a":"1", "b":"c BEGIN 70514 END"},
{"a":"2", "b":"d BEGIN 99405 END"},
{"a":"3", "b":"e BEGIN 32648 END"},
{"a":"4", "b":"f BEGIN 75761 END"}
]
CodePudding user response:
Perl to the rescue!
perl -pe '$r = int(rand 9000) 1000; s/BEGIN END/BEGIN $r END/' myjson.json
-p
reads the input line by line, runs the code for each line and prints the result;- See rand and int for details, the formula creates random numbers in the interval of 1000 - 9999.
To make the numbers unique, you can use
perl -MList::Util=shuffle -pe '
BEGIN { @r = shuffle(1000 .. 9999) }; s/BEGIN END/BEGIN $r[$i ] END/'