मैं एक बहु-पंक्ति स्ट्रिंग को बदलने के लिए sed का उपयोग कैसे कर सकता हूं?


243

मैंने देखा है कि, यदि मैं \nउपयोग करने के प्रतिस्थापन के लिए एक पैटर्न में जोड़ता हूं, तो sedयह मेल नहीं खाता। उदाहरण:

$ cat > alpha.txt
This is
a test
Please do not
be alarmed

$ sed -i'.original' 's/a test\nPlease do not/not a test\nBe/' alpha.txt

$ diff alpha.txt{,.original}

$ # No differences printed out

में इससे कैसे चला सकता हूँ?


यहां स्मार्ट वर्कअराउंड: unix.stackexchange.com/a/445666/61742 । बेशक यह प्रदर्शन नहीं है! आपकी आवश्यकताओं के अनुसार प्रतिस्थापित करने के लिए अन्य अच्छे विकल्प अजीब, खराब और अजगर हो सकते हैं। कई अन्य हैं, लेकिन मेरा मानना ​​है कि विभिन्न लिनक्स वितरण (उदाहरण के लिए) में awk सबसे सार्वभौमिक है। धन्यवाद!
एडुआर्डो लुसियो

जवाबों:


235

Sed की सरलतम कॉलिंग में , यह पैटर्न स्पेस में टेक्स्ट की एक पंक्ति है, अर्थात। \nइनपुट से सीमांकित पाठ की 1 पंक्ति । पैटर्न स्पेस में सिंगल लाइन में कोई नहीं है \n... यही कारण है कि आपके रेगेक्स को कुछ भी नहीं मिल रहा है।

आप पैटर्न-स्पेस में कई लाइनों को पढ़ सकते हैं और चीजों को आश्चर्यजनक रूप से अच्छी तरह से जोड़-तोड़ कर सकते हैं, लेकिन सामान्य प्रयास से अधिक के साथ .. एसड में कमांड का एक सेट होता है जो इस प्रकार की अनुमति देता है ... यहाँ sed के लिए कमांड सारांश का एक लिंक है । यह सबसे अच्छा है जो मैंने पाया है, और मुझे लुढ़क गया।

हालाँकि आप "वन-लाइनर" विचार को भूल जाते हैं जब आप sed के माइक्रो-कमांड का उपयोग करना शुरू करते हैं। जब तक आप इसे महसूस नहीं करते हैं, तब तक इसे एक संरचित कार्यक्रम की तरह रखना उपयोगी है ... यह आश्चर्यजनक रूप से सरल है, और समान रूप से असामान्य है। आप इसे टेक्स्ट एडिटिंग की "असेंबलर भाषा" के रूप में सोच सकते हैं।

सारांश: सरल चीजों के लिए sed का उपयोग करें, और शायद थोड़ा अधिक, लेकिन सामान्य तौर पर, जब यह एक पंक्ति के साथ काम करने से परे हो जाता है, तो ज्यादातर लोग कुछ और पसंद करते हैं ...
मैं किसी और को कुछ और सुझाव दूंगा .. मैं हूं वास्तव में निश्चित नहीं है कि सबसे अच्छा विकल्प क्या होगा (मैं sed का उपयोग करूँगा, लेकिन ऐसा इसलिए है क्योंकि मुझे अच्छी तरह से पता नहीं है।)


sed '/^a test$/{
       $!{ N        # append the next line when not on the last line
         s/^a test\nPlease do not$/not a test\nBe/
                    # now test for a successful substitution, otherwise
                    #+  unpaired "a test" lines would be mis-handled
         t sub-yes  # branch_on_substitute (goto label :sub-yes)
         :sub-not   # a label (not essential; here to self document)
                    # if no substituion, print only the first line
         P          # pattern_first_line_print
         D          # pattern_ltrunc(line+nl)_top/cycle
         :sub-yes   # a label (the goto target of the 't' branch)
                    # fall through to final auto-pattern_print (2 lines)
       }    
     }' alpha.txt  

यहाँ यह एक ही स्क्रिप्ट है, जिसे स्पष्ट रूप से पढ़ने और काम करने में मुश्किल है, लेकिन कुछ लोग इसे एक-लाइनर कहेंगे

sed '/^a test$/{$!{N;s/^a test\nPlease do not$/not a test\nBe/;ty;P;D;:y}}' alpha.txt

यहाँ मेरी आज्ञा है "धोखा-चादर"

:  # label
=  # line_number
a  # append_text_to_stdout_after_flush
b  # branch_unconditional             
c  # range_change                     
d  # pattern_delete_top/cycle          
D  # pattern_ltrunc(line+nl)_top/cycle 
g  # pattern=hold                      
G  # pattern+=nl+hold                  
h  # hold=pattern                      
H  # hold+=nl+pattern                  
i  # insert_text_to_stdout_now         
l  # pattern_list                       
n  # pattern_flush=nextline_continue   
N  # pattern+=nl+nextline              
p  # pattern_print                     
P  # pattern_first_line_print          
q  # flush_quit                        
r  # append_file_to_stdout_after_flush 
s  # substitute                                          
t  # branch_on_substitute              
w  # append_pattern_to_file_now         
x  # swap_pattern_and_hold             
y  # transform_chars                   

167
मुझे अभी गोली मार दो। सबसे खराब सिंटेक्स कभी!
गिली

53
यह एक शानदार व्याख्या है, लेकिन मैं @Gili के साथ सहमत होने के लिए इच्छुक हूं।
गोआटीतिग्रादो

11
आपकी चीट-शीट में यह सब है।
konsolebox

3
tयहां कमांड का उपयोग करने के लिए आपको एक लेबल की आवश्यकता नहीं होती है - जब एक लेबल नहीं दिया जाता है तो यह स्क्रिप्ट के अंत में शाखाओं में बँट जाता है। तो sed '/^a test$/{$!{N;s/^a test\nPlease do not$/not a test\nBe/;t;P;D}}' alpha.txtसभी परिस्थितियों में आपकी आज्ञा के समान है। बेशक इस विशेष फ़ाइल के लिए, sed '/test/{N;s/.*/not a test\nBe/}' alpha.txtएक ही बात भी करता है, लेकिन मेरा पहला उदाहरण तार्किक रूप से सभी संभव फ़ाइलों के लिए बराबर है । यह भी ध्यान रखें कि \nएक प्रतिस्थापन स्ट्रिंग में एक नई लाइन का उत्पादन नहीं होता है; आपको ऐसा करने के लिए एक वास्तविक newline के बाद एक backslash `\` की आवश्यकता है।
वाइल्डकार्ड

9
ध्यान दें कि वाक्यविन्यास GNU विशिष्ट है ( #कमांड पिछले \nR से अलग नहीं है, RHS में s)। जीएनयू के साथ sedआप -zएनयूएल सीमांकित रिकॉर्ड का उपयोग करने के लिए भी उपयोग कर सकते हैं (और यदि यह पाठ है (जो परिभाषा में एनयूएलएस नहीं है) तो पूरे इनपुट में गारा डालना)।
स्टीफन चेज़लस

181

perlइसके बजाय का उपयोग करें sed:

$ perl -0777 -i.original -pe 's/a test\nPlease do not/not a test\nBe/igs' alpha.txt
$ diff alpha.txt{,.original}
2,3c2,3
< not a test
< Be
---
> a test
> Please do not

-pi -eआपका मानक "जगह-जगह" कमांड-लाइन अनुक्रम है, और -0777 संपूर्ण फ़ाइलों को खराब करने का कारण बनता है। इसके बारे में और अधिक जानकारी प्राप्त करने के लिए पेरल्डॉक पेरलुन देखें ।


3
धन्यवाद! बहुस्तरीय काम के लिए, पर्ल नीचे हाथ जीतता है! मैंने फ़ाइल को बदलने के लिए `$ perl -pi -e 's / bar / baz /' fileA` का उपयोग करके समाप्त किया।
निकोलस टोले कॉट्रेल

3
यह बहुत सामान्य है कि मूल पोस्टर sedawk या perl के उपयोग से उत्तर मांगता है। मुझे लगता है कि यह विषय पर नहीं है, इसलिए, क्षमा करें, लेकिन मैंने एक शून्य से निकाल दिया।
रो फी

68
+1 और रॉबर्टो से असहमत। अक्सर बेहतर तरीकों की अज्ञानता के लिए विशेष रूप से पूछे जाने वाले प्रश्न। जब कोई महत्वपूर्ण प्रासंगिक अंतर नहीं होता है (जैसे यहां), तो इष्टतम समाधान को कम से कम उतना ही मिलना चाहिए जितना कि प्रश्न-विशेष वाले।
जियोथैरेपी

56
मुझे लगता है sedकि उपरोक्त उत्तर साबित करता है कि एक पर्ल उत्तर विषय पर है।
रीयरियरपोस्ट

7
थोड़ा आसान: "-p0e" के साथ "-0777" आवश्यक नहीं है। unix.stackexchange.com/a/181215/197502
Weidenrinde

96

मुझे लगता है, \nप्रतीक को किसी अन्य प्रतीक के साथ बदलना बेहतर है , और फिर हमेशा की तरह काम करना:

उदाहरण के लिए काम नहीं किया गया स्रोत कोड:

cat alpha.txt | sed -e 's/a test\nPlease do not/not a test\nBe/'

इसे बदला जा सकता है:

cat alpha.txt | tr '\n' '\r' | sed -e 's/a test\rPlease do not/not a test\rBe/'  | tr '\r' '\n'

अगर किसी को पता नहीं है, \nतो UNIX लाइन समाप्त हो रही है, \r\n- विंडोज़, \r- क्लासिक मैक ओएस। सामान्य UNIX पाठ \rप्रतीक का उपयोग नहीं करता है , इसलिए इस मामले के लिए इसका उपयोग करना सुरक्षित है।

आप अस्थायी रूप से \ n को बदलने के लिए कुछ विदेशी प्रतीक का भी उपयोग कर सकते हैं। उदाहरण के रूप में - \ f (फॉर्म फीड सिंबल)। आप यहां और अधिक प्रतीक पा सकते हैं ।

cat alpha.txt | tr '\n' '\f' | sed -e 's/a test\fPlease do not/not a test\fBe/'  | tr '\f' '\n'

11
इस चतुर हैक के लिए +1! विशेष रूप से उपयोगी एक विदेशी प्रतीक का उपयोग करने के बारे में सलाह है कि जब तक आप संपादन कर रहे फ़ाइल की सामग्री के बारे में पूरी तरह से निश्चित न हों, तब तक नई पंक्ति को बदल दें।
L0j1k

यह के रूप में इसके बजाय ओएस एक्स पर लिखा, एक के सभी उदाहरणों बदलने की जरूरत है काम नहीं करता है \rके लिए तर्क में sedसाथ $(printf '\r')
abeboparebop

@abeboparebop: शानदार खोज! 👍 वैकल्पिक रूप से, होमबॉव का उपयोग करते हुए GNU sed स्थापित करें: stackoverflow.com/a/30005262
ssc

@abeboparebop, पर OSX, तुम सिर्फ एक जोड़ने की जरूरत है $परिवर्तित करने से रोकने के sed स्ट्रिंग से पहले \rएक करने के लिए r। संक्षिप्त उदाहरण sed $'s/\r/~/':। पूर्ण उदाहरण:cat alpha.txt | tr '\n' '\r' | sed $'s/a test\rPlease do not/not a test\rBe/' | tr '\r' '\n'
wisebucky

40

माना जाता है कि सभी चीजें, संपूर्ण फ़ाइल को प्राप्त करने का सबसे तेज़ तरीका हो सकता है।

मूल सिंटैक्स निम्नानुसार है:

sed -e '1h;2,$H;$!d;g' -e 's/__YOUR_REGEX_GOES_HERE__...'

ध्यान रहे, यदि फ़ाइल जबरदस्त रूप से बड़ी हो, तो पूरी फ़ाइल को टटोलना एक विकल्प नहीं हो सकता है। ऐसे मामलों के लिए, यहां दिए गए अन्य उत्तर अनुकूलित समाधान प्रदान करते हैं जो एक छोटे मेमोरी फ़ुटप्रिंट पर काम करने की गारंटी है।

अन्य सभी हैक और स्लेश स्थितियों के लिए, केवल -e '1h;2,$H;$!d;g'आपके मूल sedregex तर्क के बाद प्रीपेडिंग का काम पूरा हो जाता है।

जैसे

$ echo -e "Dog\nFox\nCat\nSnake\n" | sed -e '1h;2,$H;$!d;g' -re 's/([^\n]*)\n([^\n]*)\n/Quick \2\nLazy \1\n/g'
Quick Fox
Lazy Dog
Quick Snake
Lazy Cat

क्या करता -e '1h;2,$H;$!d;g'है?

1, 2,$, $!भागों लाइन है कि सीमा जो लाइनों सीधे निम्न आदेश पर चलता है विनिर्देशक हैं।

  • 1: पहली पंक्ति केवल
  • 2,$: दूसरी से शुरू होने वाली सभी लाइनें
  • $!: अंतिम के अलावा हर पंक्ति

इतना विस्तारित, यह वही है जो एन लाइन इनपुट की प्रत्येक पंक्ति पर होता है।

  1: h, d
  2: H, d
  3: H, d
  .
  .
N-2: H, d
N-1: H, d
  N: H, g

gआदेश एक लाइन विनिर्देशक नहीं दिया जाता है, लेकिन पूर्ववर्ती dआदेश एक विशेष खंड है " प्रारंभ अगले चक्र। ", और इस से बचाता है gपिछले छोड़कर सभी लाइनों पर चलने से।

प्रत्येक आदेश के अर्थ के लिए:

  • पहले hके बाद Hप्रत्येक पंक्ति प्रतियों पर रों में इनपुट की तर्ज कहा sedकी पकड़ अंतरिक्ष । (मनमाना टेक्स्ट बफर सोचें।)
  • बाद में, dइन पंक्तियों को आउटपुट पर लिखे जाने से रोकने के लिए प्रत्येक पंक्ति को डिस्कस करता है। पकड़ अंतरिक्ष तथापि संरक्षित है।
  • अंत में, बहुत अंतिम पंक्ति पर, होल्ड स्पेसg से प्रत्येक लाइन के संचय को पुनर्स्थापित करता है , ताकि पूरे इनपुट पर इसकी रेगेक्स चलाने में सक्षम हो (बजाय एक लाइन-ए-टाइम के फैशन में), और इसलिए सक्षम है s पर मैच ।sed\n

38

sedमल्टी-लाइन ऑपरेशन का प्रबंधन करने के लिए तीन कमांड हैं: और N, (उनकी तुलना सामान्य से , और )।DP ndp

इस स्थिति में, आप अपने पैटर्न की पहली पंक्ति का मिलान कर सकते हैं, Nदूसरी पंक्ति को पैटर्न स्पेस में जोड़ सकते हैं और फिर sअपने प्रतिस्थापन को करने के लिए उपयोग कर सकते हैं।

कुछ इस तरह:

/a test$/{
  N
  s/a test\nPlease do not/not a test\nBe/
}

2
यह कमाल का है! स्वीकृत उत्तर की तुलना में सरल और अभी भी प्रभावी है।
जेके

और यह सब पकड़ अंतरिक्ष (शामिल लोगों G, H, x...)। sकमांड के साथ पैटर्न लाइनों में और अधिक लाइनें जोड़ी जा सकती हैं ।
स्टीफन चेजलस


यह समाधान निम्नलिखित मामले के साथ काम नहीं करता है "यह \ na test \ na test \ n कृपया चिंतित न हों \ n"
m89896

@ mug896 आप सबसे अधिक संभावना कई Nआदेशों की जरूरत है
loa_in_

15

आप कर सकते हैं लेकिन यह मुश्किल है । मैं एक अलग टूल पर स्विच करने की सलाह देता हूं। यदि एक नियमित अभिव्यक्ति है जो आपके द्वारा प्रतिस्थापित किए जाने वाले पाठ के किसी भी भाग से मेल नहीं खाती है, तो आप इसे GNU awk में एक awk record विभाजक के रूप में उपयोग कर सकते हैं।

awk -v RS='a' '{gsub(/hello/, "world"); print}'

यदि आपकी खोज स्ट्रिंग में कभी भी लगातार दो नई लाइनें नहीं हैं, तो आप awk के "पैराग्राफ मोड" (एक या अधिक रिक्त लाइनों को अलग रिकॉर्ड) का उपयोग कर सकते हैं।

awk -v RS='' '{gsub(/hello/, "world"); print}'

एक आसान समाधान पर्ल का उपयोग करना है और फ़ाइल को पूरी तरह से मेमोरी में लोड करना है।

perl -0777 -pe 's/hello/world/g'

1
एक फ़ाइल में पर्ल कमांड कैसे लागू करें?
sebix

2
@sebix perl -0777 -pe '…' <input-file >output-file। जगह में एक फ़ाइल को संशोधित करने के लिए,perl -0777 -i -pe '…' filename
गाइल्स

3
यह भी देखें कि GNU sedका -zविकल्प (2012 में उत्तर पोस्ट होने के बाद जोड़ा गया) seq 10 | sed -z 's/4\n5/a\nb/':।
स्टीफन चेज़लस

7

मुझे लगता है कि यह 2 लाइनों के मिलान के लिए sed समाधान है।

sed -n '$!N;s@a test\nPlease do not@not a test\nBe@;P;D' alpha.txt

यदि आप 3 लाइनों का मिलान चाहते हैं तो ...

sed -n '1{$!N};$!N;s@aaa\nbbb\nccc@xxx\nyyy\nzzz@;P;D'

अगर आप 4 लाइनों का मिलान चाहते हैं तो ...

sed -n '1{$!N;$!N};$!N;s@ ... @ ... @;P;D'

यदि "s" कमांड में रिप्लेसमेंट पार्ट लाइनें सिकुड़ जाती हैं तो इस तरह थोड़ा और जटिल हो जाता है

# aaa\nbbb\nccc shrink to one line "xxx"

sed -n '1{$!N};$!N;/aaa\nbbb\nccc/{s@@xxx@;$!N;$!N};P;D'

यदि पुनरावृत्ति वाला हिस्सा लाइनों को बढ़ाता है तो इस तरह थोड़ा और अधिक जटिल है

# aaa\nbbb\nccc grow to five lines vvv\nwww\nxxx\nyyy\nzzz

sed -n '1{$!N};$!N;/aaa\nbbb\nccc/{s@@vvv\nwww\nxxx\nyyy\nzzz@;P;s/.*\n//M;P;s/.*\n//M};P;D'

यह शीर्ष पर अपना रास्ता बनाना चाहिए! मैंने बस दो-लाइन प्रतिस्थापन के लिए "-n" के बजाय "-i" का उपयोग किया, क्योंकि मुझे यही चाहिए, और संयोग से, यह प्रश्नकर्ता के उदाहरण में भी है।
नागदेव

5
sed -i'.original' '/a test/,/Please do not/c not a test \nBe' alpha.txt

यहाँ /a test/,/Please do not/(बहु लाइन) पाठ का एक ब्लॉक के रूप में माना जाता है, cहै परिवर्तन आदेश नया पाठ के बादnot a test \nBe

पाठ को प्रतिस्थापित करने के मामले में बहुत लंबा है, मैं पूर्व सिंटैक्स का सुझाव दूंगा।


उफ़ समस्या यह है कि एसईडी के बीच / एक परीक्षण सभी अंतिम पाठ का स्थान ले लेगा / और है / कृपया नहीं / के रूप में अच्छी तरह से करना ... :(
noonex

4
sed -e'$!N;s/^\(a test\n\)Please do not be$/not \1Be/;P;D' <in >out

बस इनपुट पर अपनी खिड़की को थोड़ा चौड़ा करें।

यह बहुत आसान है। मानक प्रतिस्थापन के अलावा; आप केवल जरूरत है $!N, Pऔर Dयहाँ।


4

पर्ल के अलावा, धाराओं और (फ़ाइलों के लिए भी) बहु-संपादन के लिए एक सामान्य और आसान तरीका है:

उदाहरण के लिए पहले कुछ नए UNIQUE लाइन सेपरेटर बनाएं जैसे कि

$ S=__ABC__                     # simple
$ S=__$RANDOM$RANDOM$RANDOM__   # better
$ S=$(openssl rand -hex 16)     # ultimate

फिर आपके sed कमांड (या किसी भी अन्य टूल) में आप \ n $ {S} द्वारा प्रतिस्थापित करते हैं, जैसे

$ cat file.txt | awk 1 ORS=$S |  sed -e "s/a test${S}Please do not/not a test\nBe/" | awk 1 RS=$S > file_new.txt

(awk आपकी और इसके विपरीत ASCII लाइन विभाजक की जगह लेता है।)


2

यह ओएस एक्स पर काम करने के लिए ज़ारा के चतुर जवाब का एक छोटा संशोधन है (मैं 10.10 का उपयोग कर रहा हूं):

cat alpha.txt | tr '\n' '\r' | sed -e 's/a test$(printf '\r')Please do not/not a test$(printf '\r')Be/'  | tr '\r' '\n'

स्पष्ट रूप से उपयोग करने के बजाय \r, आपको उपयोग करना होगा $(printf '\r')


1
जबकि printf '\r'(या echo -e '\r') ठीक से काम करते हैं, कृपया ध्यान दें कि आप $'\r'बची हुई शाब्दिकता को संदर्भित करने के लिए शेल सिंटैक्स का उपयोग कर सकते हैं । उदाहरण के लिए, के echo hi$'\n'thereबीच एक नई पंक्ति गूंज जाएगा hiऔर there। इसी तरह, आप पूरे तार को लपेट सकते हैं ताकि प्रत्येक \ echo $'hi\nthere'
बैकलैश

1

मैं सीड का उपयोग कर एक फ़ाइल में HTML की कुछ पंक्तियों को जोड़ना चाहता था, (और यहाँ समाप्त हुआ)। आम तौर पर मैं सिर्फ पर्ल का उपयोग करता हूं, लेकिन मैं उस बॉक्स पर था जिसमें sed, bash और बहुत कुछ नहीं था। मैंने पाया कि अगर मैंने स्ट्रिंग को सिंगल लाइन में बदल दिया और bash / sed को \ t \ n सब कुछ काम करने के लिए इंटरपोलेट कर दिया:

HTML_FILE='a.html' #contains an anchor in the form <a name="nchor" />
BASH_STRING_A='apples'
BASH_STRING_B='bananas'
INSERT="\t<li>$BASH_STRING_A<\/li>\n\t<li>$BASH_STRING_B<\/li>\n<a name=\"nchor\"\/>"
sed -i "s/<a name=\"nchor"\/>/$INSERT/" $HTML_FILE

डबल कोट्स और फ़ॉरवर्ड-स्लैश से बचने के लिए फंक्शन करना क्लीनर होगा, लेकिन कभी-कभी एब्सट्रैक्शन समय का चोर होता है।


1

जीएनयू के sedपास एक -zविकल्प है जो सिंटैक्स ओपी को लागू करने का प्रयास करने की अनुमति देता है। ( मैन पेज )

उदाहरण:

$ cat alpha.txt
This is
a test
Please do not
be alarmed
$ sed -z 's/a test\nPlease do not\nbe/not a test\nBe/' -i alpha.txt
$ cat alpha.txt
This is
not a test
Be alarmed

जागरूक रहें: यदि आप उपयोग करते हैं ^और $वे अब NUL वर्ण (नहीं \n) के साथ सीमांकित लाइनों की शुरुआत और अंत से मेल खाते हैं । और, यह सुनिश्चित करने के लिए कि आपकी सभी ( \n-पारंक्षित) लाइनों पर मैच लगाए गए हैं, gवैश्विक प्रतिस्थापन (जैसे s/.../.../g) के लिए ध्वज का उपयोग करना न भूलें ।


क्रेडिट: @ स्टीफन-चेज़लस ने पहली -z का उल्लेख एक टिप्पणी में किया था।


0

सैड ने न्यूलाइन पर इनपुट तोड़ दिया। यह प्रति पाश केवल एक पंक्ति रखता है।
इसलिए \nपैटर्न स्पेस में नहीं होने पर (न्यूलाइन) से मेल खाने का कोई तरीका नहीं है।

एक तरीका है, हालाँकि, आप लूप का उपयोग करके पैटर्न स्पेस में दो लगातार लाइनें बना सकते हैं :

sed 'N;l;P;D' alpha.txt

एन और पी (के स्थान पर l) के बीच आवश्यक किसी भी प्रसंस्करण को जोड़ें ।

इस मामले में (2 लाइनें):

$ sed 'N;s/a test\nPlease do not/not a test\nBe/;P;D' alpha.txt
This is
not a test
Be
be alarmed

या, तीन पंक्तियों के लिए:

$ sed -n '1{$!N};$!N;s@a test\nPlease do not\nbe@not a test\nDo\nBe@;P;D' alpha.txt 
This is
not a test
Do
Be alarmed

यह मानते हुए कि लाइनों की समान मात्रा को प्रतिस्थापित किया जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.