एक HTML फ़ाइल में एक बहु-पंक्ति पैटर्न को प्रतिस्थापित करना


4

मेरे पास HTML फ़ाइलों की एक श्रृंखला है जिसमें इस तरह दो लाइनें हैं:

<body>
<h1>Title</h1><p>
<a href="url">Description</a><br>

मैं इस पाठ को बाश स्क्रिप्ट का उपयोग करके किसी और चीज़ से बदलना चाहता हूं। मैं कोशिश कर रहा हूँ

sed -i -r 's/<h1>Title.*?$\/^.*?<br>/Replacement text/1' filename.html

लेकिन यह काम नहीं कर रहा है। मुझे संदेह है कि यह नई लाइन पर अटक रहा है और यह नहीं जानता कि समस्या के चारों ओर कैसे जाना है।

किसी भी मदद की सराहना की। sedजब तक यह काम करता है तब तक अन्य लिनक्स टूल्स का सुझाव देने के लिए स्वतंत्र महसूस करें !


1
क्या आपको वास्तव में इसके लिए आवश्यकता sedहै? sedलाइन-बाय-लाइन पढ़ता है, इसलिए मल्टी-लाइन टेक्स्ट को बदलना थोड़ा कठिन है।
slhck

मुझे sed का उपयोग नहीं करना है। मैं अन्य लिनक्स कमांड के लिए खुला हूं।
करने के लिए

हाँ कई लाइनों को पार करने वाला एक पैटर्न सेड के लिए एक समस्या हो सकती है।
बार्लोप

जवाबों:


9

मैं इसके लिए पर्ल का उपयोग करूंगा:

perl -0pe 's/<h1>Title.*\n.*<br>/replacement/' filename.html

यहां, लाइन-बाय-लाइन पढ़ने के बजाय चरित्र -0पर पर्ल विभाजन रिकॉर्ड बनाता है NUL, जो -pविकल्प का उपयोग करते समय डिफ़ॉल्ट होता है।

पर्ल रेगुलर एक्सप्रेशंस के साथ आपको .* किसी भी कैरेक्टर को कई बार मैच करना होगा, और आप न्यूलाइन के साथ मैच करेंगे \n

उदाहरण:

$ echo '<body>
<h1>Title</h1><p>
<a href="url">Description</a><br>' | perl -0pe 's/<h1>Title.*\n.*<br>/replacement/'
<body>
replacement


2
यह लगभग अच्छा है। मैंने जोड़ा? दो के बाद। * लालच को निष्क्रिय करने के लिए। क्या STDOUT को आउटपुट करने के बजाय कमांड को फाइल को संशोधित करना संभव है?
करने के लिए

3
@ToDo पर्ल -iविकल्प के साथ इन-प्लेस संपादन कर सकता है, इसलिए perl -0p -i~ -e 's/…/…/'मूल फ़ाइल को संपादित करने के लिए इसे चलाएं , ~प्रत्यय के साथ एक बैकअप प्रतिलिपि बनाएं । या, बैकअप फ़ाइल के बिना बदलने के लिए, कॉल करें perl -0pi -e …
slhck

1

sedसीधे एक से अधिक पंक्ति से मेल नहीं खा सकता। जब मल्टीलाइन पैटर्न की आवश्यकता होती है, तो पर्ल जैसे अधिक शक्तिशाली उपकरण के लिए पहुंचें:

perl -i~ -ne 'if (/^<h1>Title/) {
                  $n = <>;
                  if ($n =~ /<br>$/) { print "Replacement\n" }
                  else { print "$_$n" }
              } else { print }'

1

यह सेड के साथ किया जा सकता है।

sed -nf repl.sed filename.html

जिसमें repl.sedशामिल हैं:

# Must have one line loaded up before branching to rep.
# Processing will start this way.
:rep
# Load extra line into pattern space
N
# Test for title
/<h1>.*<\/h1><p>\n<a href=".*">.*<\/a><br>/{
  #Substitute and print
  s/<h1>\(.*\)<\/h1><p>\n<a href=".*">.*<\/a><br>/Title: \1/p
  #append next line without cycling
  N
  # everything but the last line
  s/.*\n\([.\n]*\)/\1/
  #test for last line
  ${
    p
    # this will effectively end the program
    n
  }
  b rep
}
${
  # will print pattern space (both lines)
  p
  # this will effectively end the program
  n
}
#Print first line in pattern space
P;
#Remove first line in pattern space with newline
s/.*\n\([.\n]*\)/\1/
b rep

मल्टीपल लाइन्स के साथ कार्य करना देखें

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