Cách trích xuất chuỗi giữa hai \ n trong một tệp


7

Tôi có một tập tin với mẫu

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

Tôi muốn các giá trị 29, 3 ngày, 59, v.v.

về cơ bản là giá trị giữa \n value \n

Tôi đã tham khảo nhiều nơi nhưng tôi không biết làm cách nào để thoát khỏi các ký tự.

Tôi đã thử: - grep -o '\n.*\n' o.txt Nhưng nó không hoạt động


Đừng phân tích cú pháp XML hoặc HTML bằng các biểu thức thông thường . Nó không hoạt động đáng tin cậy .
cas

Từ liên kết bạn vừa đăng. ... but I think that's just as wrongheaded as demanding every trivial HTML processing task be handled by a full-blown parsing engine.. Việc sử dụng một biểu thức thông thường để lấy một số văn bản từ một tệp không phải là một tội ác. Tôi đã nghe rất nhiều người thuyết giáo rằng bạn không nên làm điều đó, nhưng hoàn toàn không có gì sai khi thực hiện nó ở quy mô nhỏ nếu bạn biết bạn đang làm gì.
Klik

1
Đó không phải là một tội ác, nhưng nó không bao giờ là một ý tưởng tốt để tạo ra các kịch bản mỏng manh. tất cả chỉ là một thay đổi nhỏ trong dữ liệu XML hoặc HTML và trích xuất regrec của bạn sẽ bị hỏng. sử dụng một trình phân tích cú pháp sẽ đối phó với những thay đổi tốt. vì vậy, tạo các chương trình dễ vỡ là sai - đôi khi chỉ hoạt động đôi khi bị hỏng. btw, không chỉ về việc bạn "biết bạn đang làm gì", mà chủ yếu là về thực tế là bạn không thể chắc chắn rằng dữ liệu XML / HTML sẽ không thay đổi. Ngoài ra, hầu hết những người nghĩ rằng họ biết những gì họ đang làm không.
cas

Câu trả lời:


9

Grep diễn giải \nnhư một nhân vật dòng mới. Có vẻ như tệp của bạn không có ký tự dòng mới, nó đã được \theo sau n. Để tìm kiếm dấu gạch chéo ngược theo nghĩa đen, bạn phải nhân đôi chúng:

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

Với GNU grep, đầu ra có thể dễ dàng được dọn sạch để loại bỏ \n:

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

Ở đây, (?<=\\n)là một xác nhận nhìn phía sau và (?=\\n)là một xác nhận nhìn về phía trước để yêu cầu rằng văn bản mà chúng ta khớp được bao quanh \n. Mặc dù grep trả về các kết quả không trùng lặp, nhưng một điều tinh tế ở đây là phần nhìn phía sau và phần nhìn không được tính vào trận đấu. Điều này khiến chúng ta gặp phải vấn đề mà văn bản mà chúng ta không muốn cũng bị bao vây \n. Ví dụ: trong o.txt, các ký tự \n<br/><font style="font-size:smaller;font-weight:normal">\nđược bao quanh bởi \n. Để loại bỏ các chuỗi này, chúng tôi yêu cầu văn bản phù hợp loại trừ không chỉ \mà còn <>.

Nếu chúng ta không có GNU grep, một tùy chọn khác là sử dụng sedđể dọn sạch đầu ra:

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

Một tùy chọn khác là sử dụng awk:

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

Ở đây, awk đang sử dụng \theo sau nlà dấu phân cách bản ghi và chúng tôi chỉ in các bản ghi được đánh số chẵn.


Điều này hoạt động, nhưng tôi cũng nhận được đầu ra với \ n, làm thế nào để chỉ nhận các giá trị?
penta

Mát mẻ. Bạn có thể giải thích những gì [^\\<>]*trong biểu thức grep thứ 2?
Raul

@Rahul Cái đó khá tinh tế. Tôi chỉ cập nhật câu trả lời với một lời giải thích.
John1024
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.