各行にランダムな文字列を追加するにはどうすればよいですか?


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

回答:


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-function


いいですが、なぜ私は得てい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問題を引き起こしている場合は、その8進数に相当するものに置き換えます(\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入力の行ごとに1つのインスタンスを実行すると、逆効果になります。

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

入力にバッククォートも単一引用符も含まれていない場合は、m4's も使用できますmkstemp()

<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パイプラインは、標準入力にランダムな6文字の文字列の無限ストリームを生成しますawkawkファイル名が指定されている場合、標準入力は無視されるため、これらのランダム文字列はgetlinefromから/dev/stdinvariableに読み込まれます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には1つの列のみを含める必要があります。つまり、デフォルトのセパレーターby awkおよびpaste(タブ文字のみ)コマンドとして使用されるため、タブやスペースを含めることはできません。それ以外の場合は、コマンドを少し変更する必要があります。

注: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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.