用随机数替换文件中的重复数字

Abh*_*hra 4 string bash sed

我想使用"sed"在文件的每一行中用随机数替换所有出现的数字.例如,如果我的文件在每行中的编号为892,我想用800到900之间的唯一随机数替换它.

输入文件:-

temp11;djaxfile11;892  
temp12;djaxfile11;892  
temp13;djaxfile11;892  
temp14;djaxfile11;892  
temp15;djaxfile11;892
Run Code Online (Sandbox Code Playgroud)

预期的输出文件: -

temp11;djaxfile11;805  
temp12;djaxfile11;846  
temp13;djaxfile11;833  
temp14;djaxfile11;881  
temp15;djaxfile11;810
Run Code Online (Sandbox Code Playgroud)

我正在尝试下面的内容: -

sed -i -- "s/;892/;`echo $RANDOM % 100 + 800 | bc`/g" file.txt
Run Code Online (Sandbox Code Playgroud)

但它正在用800到900之间的单个随机数替换892的所有出现次数.

输出文件 :-

temp11;djaxfile11;821  
temp12;djaxfile11;821  
temp13;djaxfile11;821  
temp14;djaxfile11;821  
temp15;djaxfile11;821
Run Code Online (Sandbox Code Playgroud)

你能帮忙纠正我的代码吗?提前致谢.

Win*_*ute 7

使用GNU sed,你可以做类似的事情

sed '/;892$/ { h; s/.*/echo $((RANDOM % 100 + 800))/e; x; G; s/892\n// }' filename
Run Code Online (Sandbox Code Playgroud)

...但用awk做它会更加理智:

awk -F \; 'BEGIN { OFS = FS } $NF == 892 { $NF = int(rand() * 100 + 800) } 1' filename
Run Code Online (Sandbox Code Playgroud)

要确保随机数是唯一的,请按如下方式修改awk代码:

awk -F \; 'BEGIN { OFS = FS } $NF == 892 { do { $NF = int(rand() * 100 + 800) } while(!seen[$NF]++) } 1'
Run Code Online (Sandbox Code Playgroud)

用sed这样做对我来说太疯狂了.请注意,这仅在文件中最后一个字段为892的行少于100行时才有效.

说明

sed代码读取

/;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
}
Run Code Online (Sandbox Code Playgroud)

awk代码更直接.有了-F \;,我们告诉awk以分号分割行

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.
Run Code Online (Sandbox Code Playgroud)

修改后的awk代码替换

$NF = int(rand() * 100 + 800)
Run Code Online (Sandbox Code Playgroud)

do {
  $NF = int(rand() * 100 + 800)
} while(!seen[$NF]++)
Run Code Online (Sandbox Code Playgroud)

...换句话说,它保留了一张已经使用的随机数字表,并保持绘制数字直到它得到一个之前没有见过的数字.