I want to replace all occurrences of a number with a random number in each line of a file using "sed". For example, if my file has the number 892 in each line, I would like to replace that with a unique random number between 800 and 900.
Input file:-
temp11;djaxfile11;892
temp12;djaxfile11;892
temp13;djaxfile11;892
temp14;djaxfile11;892
temp15;djaxfile11;892
Expected output file :-
temp11;djaxfile11;805
temp12;djaxfile11;846
temp13;djaxfile11;833
temp14;djaxfile11;881
temp15;djaxfile11;810
I am trying the below:-
sed -i -- "s/;892/;`echo $RANDOM % 100 + 800 | bc`/g" file.txt
but it is replacing all the occurrences of 892 with a single random number between 800 and 900.
Output file :-
temp11;djaxfile11;821
temp12;djaxfile11;821
temp13;djaxfile11;821
temp14;djaxfile11;821
temp15;djaxfile11;821
Could you please help in correcting my code ? Thanks in advance.
With GNU sed, you could do something like
sed '/;892$/ { h; s/.*/echo $((RANDOM % 100 + 800))/e; x; G; s/892\n// }' filename
...but it would be much saner to do it with awk:
awk -F \; 'BEGIN { OFS = FS } $NF == 892 { $NF = int(rand() * 100 + 800) } 1' filename
To make sure that the random numbers are unique, amend the awk code as follows:
awk -F \; 'BEGIN { OFS = FS } $NF == 892 { do { $NF = int(rand() * 100 + 800) } while(!seen[$NF]++) } 1'
Doing that with sed would be too crazy for me. Be aware that this will only work only if there are less than 100 lines with a last field of 892 in the file.
The sed code reads
/;892$/ { # if a line ends with ;892
h # copy it to the hold buffer
s/.*/echo $((RANDOM % 100 + 800))/e # replace the pattern space with the
# output of echo $((...))
# Note: this is a GNU extension
x # swap pattern space and hold buffer
G # append the hold buffer to the PS
# the PS now contains line\nrandom number
s/892\n// # remove the old field and the newline
}
The awk code is much more straightforward. With -F \;
, we tell awk to split the lines at semicolons, then
BEGIN { OFS = FS } # output field separator is input FS, so the output
# is also semicolon-separated
$NF == 892 { # if the last field is 892
# replace it with a random number
$NF = int(rand() * 100 + 800)
}
1 # print.
The amended awk code replaces
$NF = int(rand() * 100 + 800)
with
do {
$NF = int(rand() * 100 + 800)
} while(!seen[$NF]++)
...in other words, it keeps a table of random numbers it has already used and keeps drawing numbers until it gets one it hasn't seen before.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With