Memformat ulang banyak file XML


11

Saya memanipulasi sejumlah besar file XML yang tersebar di seluruh struktur direktori bersarang.

Saya mencoba yang berikut ini:

$ find . -name "*.xml" -type f | xargs -- xmllint --format

Masalahnya adalah bahwa menghasilkan output XML diformat di layar, tetapi tidak mengubah file.

Bagaimana saya bisa mengubah perintah ini sehingga isi file yang sebenarnya diubah?

Jawaban:


23

Ini dapat dilakukan dengan findlangsung menggunakan -exec:

find . -name "*.xml" -type f -exec xmllint --output '{}' --format '{}' \;

Apa yang diteruskan -execakan dipanggil sekali per file yang ditemukan dengan parameter template {}diganti dengan nama file saat ini. Perintah \;di akhir find hanya mengakhiri baris.

Penggunaan kata xargstidak benar-benar diperlukan dalam kasus ini karena kita perlu memanggil xmllintsekali per file karena nama file input dan output harus ditentukan dalam panggilan yang sama.

xargsakan diperlukan jika perintah yang dikirim ke dari find bekerja pada beberapa file sekaligus dan daftar itu panjang. Anda tidak dapat melakukan itu dalam kasus ini, karena Anda harus meneruskan nama file tunggal ke --outputopsi xmllint. Tanpa xargsAnda bisa berakhir dengan kesalahan "Daftar Argumen terlalu lama" jika Anda memproses banyak file. xargsjuga mendukung string ganti file dengan -Iopsi:

find . -name "*.xml" -type f | xargs -I'{}' xmllint --output '{}' --format '{}'

Akan melakukan hal yang sama seperti find -execperintah di atas. Jika ada folder Anda yang memiliki karakter aneh di ruang yang sama, Anda harus menggunakan -0opsi finddan xargs. Tetapi menggunakan xargsdengan -Imenyiratkan opsi -L 1yang berarti hanya memproses 1 file pada satu waktu, jadi Anda mungkin juga langsung menggunakan finddengan -exec.


@manatwork terima kasih untuk suntingan - jari lengket; o)
didster

Saya baru saja menjalankan ini dan tampaknya berhasil! Terima kasih banyak atas respons yang cepat dan ringkas!
Harry

2
“Ini akan gagal jika daftar file terlalu besar”: Tidak, itu tidak akan gagal (ini memproses satu file pada satu waktu), dan sebenarnya find … -execadalah cara paling langsung untuk melakukan ini.
Gilles 'SANGAT berhenti menjadi jahat'

@Gilles Poin bagus! Saya telah memperbarui jawaban saya sesuai dengan itu.
Didster

1
Ini berfungsi karena fakta bahwa xmllintpertama memuat dokumen xml penuh ke dalam memori dan hanya kemudian mengurai / menulis. Ini memungkinkan pemrosesan dokumen di tempat.
gavenkoa

6

Saya biasanya menyerang masalah ini dengan lapisan tipuan. Tulis skrip shell yang melakukan apa yang Anda inginkan, dan panggil itu. Saya sarankan sebagai permulaan

#! /bin/sh
for file
do
   xmllint --format $file > $file.tmp && mv $file.tmp $file
done

Coba saja pada satu atau dua file dengan tangan, maka Anda bisa menggantinya di xargs

find . -name "*.xml" -type f | xargs -- xmltidy.sh

Ini terlihat seperti pendekatan yang baik jika saya harus melakukan manipulasi yang lebih kompleks di masa depan. Terima kasih atas tanggapannya.
Harry
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.