Reputation: 2269
I successfully am able to replace UUIDs with freshly generated UUIDDs in a file:
FILE=/home/username/sql_inserts_with_uuid.sql
grep -i -o -E "([a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12})" $FILE | xargs -I {} sed -i "s/{}/`uuidgen -t`/g" $FILE
But its slow because it rewrites the file for each UUID it generates. Is there a more efficient way to rewrite every UUID in a single pass instead of rewriting the same file over and over?
Save this sample data in a file to test:
INSERT INTO fake_table (uuid) VALUES ('812ab76e-43ca-11ec-b54f-00d8617c2296');
INSERT INTO fake_table (uuid) VALUES ('854f7b36-43ca-11ec-9608-00d8617c2296');
INSERT INTO fake_table (uuid) VALUES ('8a09444a-43ca-11ec-8ae2-00d8617c2296');
INSERT INTO fake_table (uuid) VALUES ('8cd0da58-43ca-11ec-9811-00d8617c2296');
INSERT INTO fake_table (uuid) VALUES ('8f9889c0-43ca-11ec-8bfc-00d8617c2296');
Upvotes: 2
Views: 329
Reputation: 10123
In plain bash:
cat new_uuids
#!/bin/bash
hex='[[:xdigit:]]'
hex3="$hex$hex$hex"
hex4="$hex3$hex"
hex8="$hex4$hex4"
hex12="$hex8$hex4"
pat="$hex8-$hex4-[0-9]$hex3-[89aAbB]$hex3-$hex12"
while IFS= read -r line; do
if [[ $line = *$pat* ]]; then
echo "${line/$pat/$(uuidgen -t)}"
else
echo "$line"
fi
done
Call it as
./new_uuids < sql_inserts_with_uuid.sql > new_sql_inserts_with_uuid.sql
Upvotes: 1
Reputation: 103774
You can use awk
with a system call to replace them all in one pass:
awk '
BEGIN{pat="[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[0-9][a-fA-F0-9]{3}-[89aAbB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}"}
function get_uuid(){
cmd = "uuidgen"
cmd | getline uuid
close(cmd)
return uuid
}
$0~pat{
uuid=get_uuid()
sub(pat,uuid,$0)
} 1
' file.txt
Prints:
INSERT INTO fake_table (uuid) VALUES ('473C4331-CC31-4FD0-AE99-37FA7E5F23CF');
INSERT INTO fake_table (uuid) VALUES ('EBEC05AB-4236-4384-AF7A-76D4A0615599');
INSERT INTO fake_table (uuid) VALUES ('23740143-6CC1-41FC-8AE7-038810291026');
INSERT INTO fake_table (uuid) VALUES ('7DBF25AF-4E85-4C55-B8CA-0F6150D5DD3C');
INSERT INTO fake_table (uuid) VALUES ('4365127B-EB46-414E-92D4-B48CC211489E');
With GNU awk, you can make the replacements inplace. Otherwise, you need to redirect the output of this to a temp file then mv
the temp file on top of the source file. This sounds harder than is actually is.
Speed test: Multiplying your example file to 10,000 UUID replacements, the file is processed in 21 seconds on my computer and 26 ms if the same file has no replacements. The system call is not free in terms of efficiency but this is likely faster than what you are doing...
Upvotes: 2