用随机数替换文件中的重复数字
Replacing a repeating number in a file with random numbers
我想使用 "sed" 在文件的每一行中用一个随机数替换所有出现的数字。
例如,如果我的文件每一行都有数字 892,我想用 800 到 900 之间的唯一随机数替换它。
输入文件:-
temp11;djaxfile11;892
temp12;djaxfile11;892
temp13;djaxfile11;892
temp14;djaxfile11;892
temp15;djaxfile11;892
预期输出文件:-
temp11;djaxfile11;805
temp12;djaxfile11;846
temp13;djaxfile11;833
temp14;djaxfile11;881
temp15;djaxfile11;810
我正在尝试以下操作:-
sed -i -- "s/;892/;`echo $RANDOM % 100 + 800 | bc`/g" file.txt
但它正在用 800 到 900 之间的单个随机数替换所有出现的 892。
输出文件:-
temp11;djaxfile11;821
temp12;djaxfile11;821
temp13;djaxfile11;821
temp14;djaxfile11;821
temp15;djaxfile11;821
你能帮我改正我的代码吗?提前致谢。
使用 GNU sed,你可以做类似的事情
sed '/;892$/ { h; s/.*/echo $((RANDOM % 100 + 800))/e; x; G; s/892\n// }' filename
...但是用 awk 来做会更明智:
awk -F \; 'BEGIN { OFS = FS } $NF == 892 { $NF = int(rand() * 100 + 800) } 1' filename
为确保随机数唯一,修改awk代码如下:
awk -F \; 'BEGIN { OFS = FS } $NF == 892 { do { $NF = int(rand() * 100 + 800) } while(!seen[$NF]++) } 1'
用 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
}
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.
修改后的awk代码替换
$NF = int(rand() * 100 + 800)
和
do {
$NF = int(rand() * 100 + 800)
} while(!seen[$NF]++)
...换句话说,它会保留 table 个已经使用过的随机数,并不断抽取数字,直到它得到一个以前从未见过的随机数。
我想使用 "sed" 在文件的每一行中用一个随机数替换所有出现的数字。 例如,如果我的文件每一行都有数字 892,我想用 800 到 900 之间的唯一随机数替换它。
输入文件:-
temp11;djaxfile11;892
temp12;djaxfile11;892
temp13;djaxfile11;892
temp14;djaxfile11;892
temp15;djaxfile11;892
预期输出文件:-
temp11;djaxfile11;805
temp12;djaxfile11;846
temp13;djaxfile11;833
temp14;djaxfile11;881
temp15;djaxfile11;810
我正在尝试以下操作:-
sed -i -- "s/;892/;`echo $RANDOM % 100 + 800 | bc`/g" file.txt
但它正在用 800 到 900 之间的单个随机数替换所有出现的 892。
输出文件:-
temp11;djaxfile11;821
temp12;djaxfile11;821
temp13;djaxfile11;821
temp14;djaxfile11;821
temp15;djaxfile11;821
你能帮我改正我的代码吗?提前致谢。
使用 GNU sed,你可以做类似的事情
sed '/;892$/ { h; s/.*/echo $((RANDOM % 100 + 800))/e; x; G; s/892\n// }' filename
...但是用 awk 来做会更明智:
awk -F \; 'BEGIN { OFS = FS } $NF == 892 { $NF = int(rand() * 100 + 800) } 1' filename
为确保随机数唯一,修改awk代码如下:
awk -F \; 'BEGIN { OFS = FS } $NF == 892 { do { $NF = int(rand() * 100 + 800) } while(!seen[$NF]++) } 1'
用 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
}
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.
修改后的awk代码替换
$NF = int(rand() * 100 + 800)
和
do {
$NF = int(rand() * 100 + 800)
} while(!seen[$NF]++)
...换句话说,它会保留 table 个已经使用过的随机数,并不断抽取数字,直到它得到一个以前从未见过的随机数。