Saya memiliki banyak file XML, lebih dari 50.000.
Dalam beberapa file XML, beberapa file ditulis seperti ini
<filename>abc.JPEG<^Lilename>
^L
hanya satu karakter, tetapi saya tidak dapat menemukan apa ^L
artinya dengan Google.
Ketika saya gunakan cat
untuk mencetak konten file, itu menunjukkan seperti berikut
<filename>abc.JPEG<
ilename>
Lagi pula, saya ingin berubah <filename>abc.JPEG<^Lilename>
menjadi<filename>abc.JPEG</filename>
Saya sudah menemukan beberapa perintah untuk mengubah kata di banyak file, seperti
find . -exec perl -pi -e 's/[find_word]/[change_word]/g' {} \;
Tetapi perintah itu tidak berfungsi dalam kasus saya, karena tidak dapat mengenali kata pencarian ketika saya mengetik ^L
.
Bagaimana cara mengubah <filename>abc.JPEG<^Lilename>
ke <filename>abc.JPEG</filename>
dalam banyak file?
<\filename>
alih-alih</filename>
dalam konteks di mana\f
akan diartikan sebagai bentuk feed karakter. Anda mungkin harus melacak sumber file-file ini dan menunjukkan masalah dengan alat pembangkitnya kepada pengembang. Untuk memperbaiki file, jawaban yang diterima baik-baik saja.Jawaban:
Control-L (diwakili sebagai
^L
) adalah karakter "form feed". Dalam ASCII, ia memiliki nilai desimal 12 (L
adalah huruf ke-12 dari alfabet) atau nilai hex 0c:Anda dapat menggantinya menggunakan alat seperti sed dengan menentukan kode escape heksadesimal:
Atau, buat komposisi
^L
langsung menggunakan urutan keyboard CTRL+ V CTRL+LUntuk penggantian spesifik Anda, diberikan
kemudian
(
g
pengubah ditambahkan jika ada lebih dari satu contoh per baris).sumber
find
yang di-loop atas 50000 file-file XML dan secara otomatis diproses masing-masing (dan membuat cadangan juga).Seperti yang ditunjukkan oleh Hans-Martin Mosner dalam komentar, tampaknya seseorang menggunakan garis miring terbalik alih-alih garis miring ketika membuat XML (atau mungkin menjalankan seluruh
<filename>
bagian melalui konverter Unix-to-Windows yang terlalu bersemangat tentang garis miring).\f
adalah urutan pelarian yang jarang digunakan untuk karakter umpan bentuk, alias U + 0C atau ^ L. Jadi beberapa langkah selanjutnya dari pipeline kemudian diganti\f
dengan karakter literal U + 0C.Untungnya, U + 0C adalah karakter yang sangat langka yang tidak mungkin ditemukan dengan sengaja dalam bentuk XML apa pun. Dan karena hanya
\f
akan menghasilkan ini, sebagai lawan (katakanlah)\g
atau\k
, menemukan-dan-ganti universal yang harus memperbaiki tidak hanya</filename>
tetapi juga</folder>
,</file>
, atau apa pun yang mendapat hancur.Itu yang dilakukan oleh sed-script steeldriver; Saya hanya akan membuatnya sedikit lebih umum:
Ini berarti "(s) wap semua instance
\x0c
(yaitu, U + 0C) ke/f
, (g) secara lobal".sumber
\f
adalah karakter umpan formulir di Perl. Sepertinya file-file cacat ini dibuat oleh seseorang yang baru untuk Perl dan XML.Berikut adalah banyak perbaikan Perlier - yang juga memenuhi tujuan OP mengotomatiskan pembaruan semua file, tidak seperti jawaban yang diterima dengan sed, yang hanya akan bekerja pada satu file pada satu waktu karena tidak dipasangkan
find
.\f
hanya bisa digunakan sendiri bukan kode heksadesimalx0c
.Di sini saya telah menambahkan
-type f
ke telfind
untuk hanya mengembalikan file biasa - jika tidakfind
akan kembali.
dalam daftar, dan memicu peringatan ketika Anda mencoba mengeditnya, meskipun semuanya masih berfungsi.Saya juga membuat regex lebih mudah dilihat dengan menggunakan
x
flag yang mengabaikan spasi putih nyata, memungkinkan Anda untuk menghilangkan elemen-elemen dari regex Anda. Jika Anda tidak suka ini, ini dia tanpa:Dan dalam hal kemungkinan bahwa semua karakter umpan formulir adalah palsu dan semua harus diganti
/f
, maka Anda dapat melangsingkan satu baris lebih jauh:Anda tidak perlu menggunakan garis miring maju untuk mengelilingi elemen perintah substitusi regex Anda (
s///
) di Perl. Anda bisa menggunakan simbol apa saja. Namun, jika Anda memilih untuk menggunakan jenis simbol seperti braket apa pun, Anda harus menggunakan keduanya:s[old][new]
misalnya.Karena saya tidak menggunakan garis miring, saya tidak perlu melepaskan garis miring.
Adapun
-i.bkp
:perl -pi -e
memungkinkan Anda mengedit di tempat - tetapi jika Anda ingin asuransi tambahan jika Anda salah menemukan dan mengganti program Perl, Anda dapat memasukkan ekstensi file sehingga akan membuat salinan file asli untuk kamu. Di sini, saya sudah menggunakan.bkp
.Dalam versi terbaru dari Perl, pengeditan di tempat telah diperbarui agar lebih tangguh jika sistem Anda mengalami masalah serius seperti kehilangan daya atau kehabisan ruang disk juga. Inilah Perl penulis brian d foy pada peningkatan pengeditan di tempat di Perls baru-baru ini.
Anda harus mempertimbangkan untuk menggunakan Perl untuk tugas-tugas semacam ini, karena ini adalah bahasa pemrograman tujuan umum yang sangat kuat namun di bawah rata-rata, salah satu yang tujuan desain awalnya adalah untuk menggantikan
sed
danawk
dengan sesuatu yang jauh lebih baik.Kemampuan pencocokan regex Perl 5 dan ditingkatkan sintaks regex jauh melebihi orang-orang dari
sed
,awk
, dan memang setiap bahasa pemrograman lain selain Perl 6, membuat Perl pilihan yang paling masuk akal untuk kedua sederhana dan manipulasi regex maju.Untuk memperjelas:
sed
akan bekerja dengan baikfind
juga dan Anda juga dapat menggunakansed -i.bkp
untuk membuat cadangan dari setiap file yang diedit, tetapi sejauh yang saya tahu itu tidak menampilkan ketahanan ekstra di Perl 5.28 dan di atasnya. Itu juga menggunakan sintaks regex UNIX ® clunkier dan jauh lebih kuat.sumber