tags:

views:

111

answers:

2

I'm using this Perl one-liner (in bash) to successfully replace a string with a random one, in a given file:

perl -pi -e "s/replace\ this/`</dev/urandom tr -dc A-Za-z0-9 | head -c64`/g" example.php

However, I don't know how to replace several "replace this" with different random strings.

+8  A: 
perl -pi -e 's/replace this/join "", map { ("a" .. "z", "A" .. "Z", 0 .. 9)[rand(62)] } 1 .. 64/eg' example.php

Let's break this down into its pieces.

("a" .. "z", "A" .. "Z", 0 .. 9)

is a list that contains the characters you want to be in the random string.

[rand(62)]

This is indexing the list above at a random location (using the rand function). The 62 corresponds to the number of items in the list. The rand function returns a number between zero and the number you gave it minus one. Happily, arrays and lists are indexed starting at zero in Perl 5, so this works out perfectly. So, every time that piece of code is run, you will get one random character from the list of acceptable characters.

The map takes a code block and a list as arguments. It runs the code block and returns the result for every item in the list handed to it. The list is 1 .. 64, so the code block will run sixty-four times. Since the code block contains the code that generates a random character, the result of the map function is sixty-four random characters.

The join function takes a delimiter and a list and returns the list as a string delimited by the delimiter (e.g. join ",", "a", "b", "c" returns "a,b,c"). In this case we are using an empty string as the delimiter, so it just produces a string made up of the characters in the list (i.e. the sixty-four random characters).

Now we are ready to look at the substitution. It looks for every instance (because of the /g option) of the string "replace this" and runs the code in the replacement side (because of the /e options) and replaces the string "replace this" with the value of the last statement executed in the replacement side (in this case, the return value of join).

Chas. Owens
Works perfectly and in one line as the original, thank you very much.
fandelost
rand returns a floating point number >= 0 and < the parameter you pass (defaulting to 1). Only because array indexing is an integer contex does that become an integer from 0 to the parameter minus one.
ysth
@ysth Good point, I was sloppy in my language.
Chas. Owens
A: 

Then why not write a script

#!/bin/bash
for replace in "replace this" "replace that"
do
   rand=$(generate random here  using /dev/urandom )
   sed -i "s/$replace/$rand/" file
done
ghostdog74
This isn't a solution to the OP, he wants each occurrence of a single pattern to be replaced with a different random string. This code will replace the first occurrence only of multiple patterns with each pattern getting a different random string.
Ven'Tatsu