如何为每行添加随机字符串?


12

我正在尝试在运行时为每行添加随机字符串:

awk '{print "name" "'$ran'" "-"$0}' 'myfile'

在此之前,将生成随机字符串:

ran="$(tr -dc '[:alnum:]' </dev/urandom | head -c 6)"

问题是它将为每行打印相同的随机字符串:

nameGQz3Ek-
nameGQz3Ek-
nameGQz3Ek-

我应该怎么做才能获得每行不同的随机字符串?


代替的某种变体tr -dc '[:alnum:]' </dev/urandom | head -c 6,它使用起来会更简单,更有效地进行计算pwgen -s 6 1,或者更好的是,pwgen -s 6 $(wc -l myfile)您一口气就能准确地提供所需的所有随机字符串。
user1404316

Answers:


9

具有awk system()功能:

样品input.txt

a
b
c

awk '{ 
         printf "name";
         system("tr -dc \047[:alnum:]\047 </dev/urandom | head -c6");
         printf "-%s\n", $0
     }' input.txt

样本输出:

nameSDbQ7T-a
nameAliHY0-b
nameDUGP2S-c

system(command)
执行操作系统命令command,然后返回到awk程序

https://www.gnu.org/software/gawk/manual/gawk.html#index-system_0028_0029-功能


很好,但是为什么我要得到tr: write error: Broken pipe
user134969

@ user134969,它工作正常。确保您在命令行上没有出现任何错误
RomanPerekhrest

9

您不觉得它有点明显吗?您只需生成一次随机字符串并将其存储在ran变量中,然后将其用于所有行!

getline在管道中使用变量

awk '{
     str_generator = "tr -dc '[:alnum:]' </dev/urandom | head -c 6"
     str_generator | getline random_str
     close(str_generator)
     print "name " random_str " - " $0
}' file

使用时command | getline var,命令的输出通过管道发送getline()到变量中,也发送到变量中var

还要注意,当打开管道进行输出时,会awk记住与之关联的命令,并且对该命令的后续写入将附加到先前的写入中。我们需要对close()命令进行显式调用以防止这种情况。

如果中的嵌套单引号str_generator引起了问题,请用其八进制等效值(\047)替换

awk '{
     str_generator = "tr -dc \047[:alnum:]\047 </dev/urandom | head -c 6"
     str_generator | getline random_str
     close(str_generator)
     print "name " random_str " - " $0
}' file

8

tr -dc '[:alnum:]' </dev/urandom | head -c 6每行输入运行一个实例会适得其反,您最好这样做:

<input awk -v rng="LC_ALL=C tr -dc '[:alnum:]' </dev/urandom | fold -w 6" '
  {rng | getline r; print "name"r"-"$0}'

如果您的输入内容不包含反引号或单引号,则也可以使用m4mkstemp()

<input sed "s/.*/mkstemp(name)\`&'/" | m4

4

其他几个答案的这种变化会在以下之外生成随机字符串awk

LC_ALL=C tr -dc '[:alnum:]' </dev/urandom | fold -w 6 |
awk '{ getline r <"/dev/stdin"; printf("name%s-%s\n", r, $0) }' file

tr+ fold管道上产生的标准输入的随机六字符串层出不穷awkawk如果提供了文件名,它将忽略标准输入,因此getline将从这些随机字符串读取/dev/stdin到变量中rprintf然后使用来为文件中的行加上适当的字符串作为前缀。

给定文件

123
abc
@#$

这可能会产生

nameFI4L1S-123
name5S8Shr-abc
namebRUjzV-@#$


0
paste <(base64 -w6 /dev/urandom) input.txt | awk 'NF==2{print $1$2} NF!=2{exit}'

要求 -input.txt应该仅包含一列,换句话说,它不应包含制表符或空格,因为它们由awkpaste(仅制表符)命令用作默认分隔符。否则,必须对命令进行一些修改。

注:Base64编码字母包含+/字符:Base64编码表,如果你想只有数字和字母,您可以使用base32命令- Base32字母表

输入值

===my_line_a
===my_line_b
===my_line_c
===my_line_d
===my_line_e

=== 为清楚起见添加了字符。

输出量

LYSdm8===my_line_a
5sSSNt===my_line_b
YVMdkA===my_line_c
3b/nsT===my_line_d
xt/AZO===my_line_e
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.