So extrahieren Sie die Zeichenfolge zwischen zwei \ n in einer Datei

7

Ich habe eine Datei mit Muster

    <span class="WebRupee">Rs.</span>\n29\n<br/><font style="font-size:smaller;font-weight:normal">\n3 days\n</font></td>, <td class="pricecell"><span class="WebRupee">Rs.</span>\n59\n<br/><font style="font-size:smaller;font-weight:normal">\n7 days\n</font></td>, <td class="pricecell"><span class="WebRupee">Rs.</span>\n99\n<br/><font style="font-size:smaller;font-weight:normal">\n12 days\n</font></td>

Ich möchte die Werte 29, 3 Tage, 59 usw.

im Grunde der Wert zwischen \n value \n

Ich habe viele Orte konsultiert, weiß aber nicht, wie ich den \ n Zeichen entkommen kann.

Ich habe versucht: - grep -o '\n.*\n' o.txt Aber es hat nicht funktioniert

Penta
quelle
Analysieren Sie XML oder HTML nicht mit regulären Ausdrücken . Es funktioniert nicht zuverlässig .
Cas
Über den Link, den Sie gerade gepostet haben. ... but I think that's just as wrongheaded as demanding every trivial HTML processing task be handled by a full-blown parsing engine.. Es ist kein Verbrechen, einen regulären Ausdruck zu verwenden, um Text aus einer Datei zu erhalten. Ich habe so viele Leute predigen hören, dass Sie es nicht tun sollten, aber es ist absolut nichts Falsches daran, es in kleinem Maßstab zu tun, wenn Sie wissen, was Sie tun.
Klik
1
Es ist kein Verbrechen, aber es ist nie eine gute Idee, fragile Skripte zu erstellen. Alles, was es braucht, ist eine geringfügige Änderung der XML- oder HTML-Daten, und Ihre Regexp-Extraktion wird unterbrochen. Die Verwendung eines Parsers wird Änderungen problemlos bewältigen. Das Erstellen fragiler Programme ist also falsch - etwas, das nur manchmal funktioniert, ist kaputt. Übrigens geht es nicht nur darum, ob Sie "wissen, was Sie tun", sondern vor allem darum, dass Sie nicht sicher sein können, dass sich die XML / HTML-Daten nicht ändern. Außerdem tun es die meisten Menschen, die glauben zu wissen, was sie tun, nicht.
Cas

Antworten:

9

Grep interpretiert \nals Zeilenumbruch. Es sieht so aus, als ob Ihre Datei keine Zeilenumbrüche enthält, \gefolgt von n. Um nach wörtlichen Backslashes zu suchen, müssen Sie diese verdoppeln:

$ grep -o '\\n[^\\]*\\n' o.txt
\n29\n
\n3 days\n
\n59\n
\n7 days\n
\n99\n
\n12 days\n

Mit GNU grep kann die Ausgabe einfach bereinigt werden, um Folgendes zu entfernen \n:

$ grep -oP '(?<=\\n)[^\\<>]*(?=\\n)' o.txt
29
3 days
59
7 days
99
12 days

Hier (?<=\\n)ist eine Rückblick-Behauptung und (?=\\n)eine Vorausschau-Behauptung, die erfordert, dass der Text, mit dem wir übereinstimmen, von umgeben ist \n. Während grep nicht überlappende Übereinstimmungen zurückgibt, besteht eine Subtilität darin, dass die Look-Behinds und Look-Aheads nicht für das Match berücksichtigt werden . Dies lässt uns mit dem Problem zurück, dass der Text, den wir nicht wollen, auch von umgeben ist \n. In o.txt sind die Zeichen \n<br/><font style="font-size:smaller;font-weight:normal">\nbeispielsweise von umgeben \n. Um diese Zeichenfolgen zu entfernen, muss der übereinstimmende Text nicht nur, \sondern auch <und ausschließen >.

Wenn wir kein GNU-Grep haben, sedkönnen Sie auch die Ausgabe bereinigen:

$ grep -o '\\n[^\\]*\\n' o.txt | sed 's/\\n//g'
29
3 days
59
7 days
99
12 days

Eine andere Option ist die Verwendung von awk:

$ awk '0==NR%2' RS='\\\\n' o.txt
29
3 days
59
7 days
99
12 days

Hier verwendet awk \gefolgt von nals Datensatztrennzeichen und wir drucken nur die geradzahligen Datensätze.

John1024
quelle
das funktioniert, aber ich bekomme auch eine Ausgabe mit \ n, wie bekomme ich nur die Werte?
Penta
Cool. Können Sie erklären, was [^\\<>]*im 2. grep-Ausdruck bedeutet?
Rahul
@ Rahul Das ist ziemlich subtil. Ich habe gerade die Antwort mit einer Erklärung aktualisiert.
John1024