मैं प्रत्येक पंक्ति के लिए यादृच्छिक स्ट्रिंग कैसे जोड़ सकता हूं?


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

अजीब 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एक समस्या पैदा कर रहे हैं, तो उसके अष्टक समकक्ष ( \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}'

अपने इनपुट बैकटिक है और न ही एकल उद्धरण शामिल नहीं है, तो आप भी इस्तेमाल कर सकते हैं m4की 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पाइप लाइन के मानक इनपुट पर यादृच्छिक छह चरित्र तार की एक अंतहीन स्ट्रीम उत्पन्न करता है awkawkयदि फ़ाइल नाम प्रदान किया गया है तो मानक इनपुट को अनदेखा कर देगा, इसलिए इन यादृच्छिक तारों को चर में getlineसे पढ़ा जाता है । फिर उपयुक्त स्ट्रिंग के साथ फाइल से लाइनों को उपसर्ग करने के लिए उपयोग किया जाता है।/dev/stdinrprintf

फाइल दी

123
abc
@#$

यह उत्पादन हो सकता है

nameFI4L1S-123
name5S8Shr-abc
namebRUjzV-@#$

1

सभी में जाग का उपयोग किए बिना, बस सरल bash

while read line; do
    printf "name%s-%s\n" \
        "$(tr -dc '[:alnum:]' </dev/urandom|head -c6)" \
        "$line"
done <myfile

1
इसके साथ समस्या यह है कि आप फ़ाइल से पढ़े गए डेटा को दूषित कर सकते हैं। देखें unix.stackexchange.com/questions/209123/...
Kusalananda

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

आवश्यकताएँ - input.txt में केवल एक कॉलम होना चाहिए, दूसरे शब्दों में, इसमें टैब या रिक्त स्थान नहीं होना चाहिए, क्योंकि वे डिफ़ॉल्ट विभाजक द्वारा 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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.