Menemukan teks CDATA multiline dalam banyak file XML (mungkin menggunakan grep)

2

Saya memiliki beberapa ribu file XML dari template berikut:

<?xml version="1.0" ?>
<queries>
  <statement name="foobar">
    <body><![CDATA[
      Several lines
      worth of
      text goes
      in here 
    ]]></body>
  </statement>
  <statement name="whatever">
    [... snip ...]
  </statement>
</queries>

Saya perlu mendapatkan daftar pernyataan-pernyataan yang isi teks dari tubuh rentang lebih dari 10 baris. Singkat penulisan skrip python untuk melakukan itu, apakah ada cara sederhana untuk menggunakan grep atau alat standar lainnya untuk melihat ke dalam setiap file dan mengembalikan pernyataan yang menjangkau banyak baris? Paling tidak, saya akan senang dengan sesuatu yang akan mengembalikan daftar nama file yang ada satu pernyataan seperti itu.

Fred
sumber

Jawaban:

2

Pendek menggunakan perpustakaan xml nyata dan / atau awk / perl / python / ruby ​​ini cukup dekat dengan apa yang Anda inginkan (jika saya mengerti Anda benar) hanya menggunakan perintah bash umum.

Harap dicatat bahwa ini benar-benar khusus untuk file xml yang digunakan dan tidak boleh didorong sebagai parser / splitter xml tujuan umum.

Anda akan memerlukan direktori keluaran untuk file yang dipecah. Saya menggunakan / tmp / out untuk contoh ini:

mkdir -p /tmp/out 

Anda harus membersihkan /tmp/outsebelum menjalankan. Kalau tidak, Anda akan mendapatkan hasil yang tidak masuk akal.

cat /path_to_xml_files/*.xml | \
egrep -v '<?xml version="1.0" \?>|<queries>|</queries>' | \
csplit -q -z - '/statement name/' '{*}' --prefix=/tmp/out/splitout- && \
for x in /tmp/out/splitout-* ; do \
[[ $(wc -l "$x"|cut -d" " -f 1) -gt 10 ]] && \
echo "$x" && \
cat "$x" ; \
done
  1. cat file xml
  2. Gunakan egrep untuk menghapus garis yang tidak diinginkan
  3. pisahkan input ke beberapa file berdasarkan contoh 'nama pernyataan' Anda
  4. hasil loop
  5. hitung baris untuk setiap file dan minta lebih dari 10
  6. cetak nama file keluaran
  7. mencetak garis keluaran

Seperti yang saya katakan, ini tidak dimaksudkan untuk menjadi splitter xml umum, tetapi harus diperlakukan sebagai contoh perintah shell yang berbeda.

Catatan: '\'-sign diikuti dengan jeda baris berarti bahwa garis berlanjut tanpa jeda baris. Ini hanya membuatnya lebih mudah dibaca.

Manwe
sumber
1

Saya hanya bisa melakukan Ruby, dengan nokogiriPermata diinstal. Saya tidak berpikir menggunakan grep akan sesederhana itu di sini, tetapi mungkin seseorang memiliki solusi yang lebih baik. Sintaksnya adalah:

ruby scriptname.rb <directory> <number-of-lines>

Jadi, misalnya:

ruby find.rb . 10

Ini akan mencantumkan semua .xmldokumen itu

  • mengandung statements
  • dengan CDATAteks
  • itu masuk body
  • yang memiliki lebih dari <number-of-lines>baris teks (>, tidak ≥)

Tidak ada pengecualian dalam penanganannya.


require 'nokogiri'
dir, lines = ARGV
@result = []
Dir.glob("#{dir}/*.xml") do |entry|
  Nokogiri::XML(File.open(entry)).xpath("//statement/body").each { |b| (@result << entry and break) if b.text.lines.count > (2+lines.to_i) }
end
puts @result
slhck
sumber