Sử dụng sed để trích xuất văn bản giữa 2 thẻ


16

Tôi có một tệp .xml và tôi đang cố thực hiện "cài đặt nhóm" trên máy RHEL6 vì có hàng trăm thư viện trong tệp .xml đó ... (gần 16 000 dòng).

Do đó, tôi đang cố trích xuất các tên nhóm có trong tệp .xml có cấu trúc này:

<b>
<group>
<id> group name </id>
   <packages>
   ...
   </packages>
<id> group name 2 </id>
   <packages>
   ...
   </packages>
<id> etc... </id>
</group>
</b>

Về cơ bản, đây là những gì tôi đã thử:

sed -n '/<id>/,/<\/id>/p' test1.txt > test2.txt

Tôi đã sao chép tệp .xml vào test1.txt. Tôi đang cố trích xuất tên nhóm từ test1.txt sang tệp thứ hai có tên test2.txt. Tuy nhiên, với dòng trên, nó đang trích xuất mọi thứ từ <id>thẻ FIRST đến </id>thẻ cuối cùng trong tệp của tôi. Làm thế nào tôi có thể thay đổi mã của mình để giải nén nó nhiều lần?

Câu hỏi thứ hai của tôi sẽ là: plugin -doadonly có hoạt động tốt với các nhóm cho yum không?


3
Trời ơi, phân tích cú pháp XML bằng regexps một lần nữa. Đó là yêu cầu rắc rối ...
gniourf_gniourf

1
Có một cái nhìn về điều này
alecail

8
Anh ta không yêu cầu phân tích cú pháp XML, nhưng để trích xuất một kết hợp byte cụ thể. Có một sự khác biệt cơ bản.
Runium

Câu trả lời:


30

Âm thanh như những gì bạn cần là một cái gì đó dọc theo dòng

sed -n 's:.*<id>\(.*\)</id>.*:\1:p'

(giả sử như trong mẫu của bạn rằng <id></id>nằm trên cùng một dòng và chỉ có một <id>...</id>dòng trên mỗi dòng).

Hoặc sử dụng công cụ nhận biết XML:

xmlstarlet sel -t -v '//id' -n

Thật là gọn gàng, chúc mừng!
fduff


1
$ echo '<id>I am a sample group</id>' | sed 's/<\/\?[^>]\+>//g'
I am a sample group
$

Điều này sẽ làm việc với bất kỳ thẻ, tất nhiên cũng với <a href="...">...</a>neo. Không có GNUism được sử dụng - hỗ trợ regex cơ bản trong sedsẽ đủ.
Tuy nhiên : xin lưu ý rằng cả hai thẻ mở và đóng phải nằm trên cùng một dòng, nếu không câu lệnh sẽ phải được viết lại.


1

Đây là XML, bạn nên sử dụng trình phân tích cú pháp XML. Đây là một giải pháp sử dụng XMLStarlet :

$ xml sel -t -v '//group/id' -nl data.xml
 group name
 group name 2

Biểu thức XPath //group/idsẽ chọn bất kỳ idnút nào bên dưới một groupnút. Có -t -vnghĩa là "sử dụng mẫu sau để trích xuất giá trị". Ở -nlcuối sẽ đảm bảo rằng đầu ra được kết thúc với một dòng mới.

Ví dụ trên sử dụng tệp XML giống hệt với tệp của bạn, nhưng với bất kỳ dòng nào có chứa ...bị xóa.


0

Tôi đọc bài viết này để tìm cách giải quyết vấn đề trích xuất Reqd. Các gói từ DVD RHEL 7.3 repos.xml, mà tôi nghĩ là chính xác những gì tác giả ở trên đã cố gắng thực hiện. Vì vậy, tôi hy vọng kịch bản này có thể giúp người khác mà tôi đã sử dụng nó nhiều lần.

Vì vậy, tôi cần phải cài đặt nhóm "Gnome DESKTOP" vào máy chủ RHEL7 "Cài đặt tối thiểu" không có cấu hình X / GUI.

[root@rac01]# yum group list
Loaded plugins: ulninfo
There is no installed groups file.

Hmmmmmạn không có danh sách nhóm trên DVD cho yum (vâng, tôi đã thử tất cả các sửa lỗi "google" thông thường và không bao giờ hoạt động) vì vậy đã sử dụng nguồn cứng từ danh sách xml.

  1. Gắn DVD.
  2. Tìm tệp XML với danh sách gói yêu cầu của tôi.
  3. Trích xuất danh sách các nhóm gói.
  4. Lặp qua danh sách các gói và cài đặt (bao gồm các phụ thuộc).
  5. Giả sử bạn đã chạy createrepo /your/local_rpms/dir.

    sudo su -
    mkdir /mnt/sr0
    mount /dev/sr0 /mnt/sr0
    cd /mnt/sr0
    
    FILE=$(find . -name "*.xml" | xargs grep '<id>gnome-desktop<\/id>'| cut -d: -f1)
    PKGLIST=$(sed -n '/<id>gnome-desktop<\/id>/,/<\/packagelist>/p' $FILE \
    | sed  -n  '/^ *<packagelist> *$/,/^ *<\/packagelist> *$/{/<packagereq type>/{d};p}' \
    | cut -d'>' -f2 \
    | cut -d'<' -f1)
    
    for p in ${PKGLIST}
       do
        yum deplist ${p}* | awk '/provider:/ {print $2}' | sort -u | xargs yum -y install
    done
    
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.