Bagaimana cara mengganti tanda kutip dalam file dengan sed?

10

Saya memiliki file yang berisi banyak baris xml. Saya ingin mengganti bagian file tertentu. Beberapa bagian file berisi tanda kutip ( ") yang ingin saya ganti. Saya telah mencoba untuk melarikan diri dari tanda kutip \, tetapi saya tidak berpikir ini berfungsi berdasarkan hasil file saya.

Berikut adalah contoh dari salah satu perintah sed saya:

sed -e "s/\"text\"/'text'/ig" file.xml > temp.tmp

Apakah ini cara Anda menghindari tanda kutip dalam perintah sed atau apakah saya melakukan sesuatu yang salah?

jranchranch
sumber
2
Perintah Anda terlihat tepat untuk menggantikan "text"dengan 'text'. Tentu saja tidak akan melakukan apa pun untuk itu "othertext". Tampilkan beberapa jalur input, output yang sesuai yang tidak diinginkan, dan jelaskan output apa yang Anda inginkan.
Gilles 'SANGAT berhenti menjadi jahat'
Jadi \"apakah cara yang benar untuk menghindari tanda kutip dalam perintah sed?
jbranchaud
4
Bukan untuk sed: sed tidak perlu, atau mendukung, melarikan diri ". Tetapi perintah shell Anda menggunakan string yang dikutip ganda, dan \"benar di sana. The sedProgram melihat s/"text"/'text'/igsebagai argumen untuk -e.
Gilles 'SO- stop being evil'
@Gilles Bagaimana dengan spasi? Apakah sed memahami dan menghormati ruang putih? Misalnya, jika perintah saya berisi s/\"text\" /'text'/igApakah ia hanya menemukan "text" spasi setelahnya?
jbranchaud
3
Spasi harus sama persis. Daripada melanjutkan dialog ini, saya sarankan Anda memposting beberapa sampel input dan output yang diinginkan yang sesuai (dan mungkin menjelaskan mengapa Anda perlu mengubah kutipan). Bahkan tidak jelas itu sedadalah alat yang tepat untuk pekerjaan itu, mungkin Anda ingin parser XML.
Gilles 'SO- stop being evil'

Jawaban:

11

Dua tips:

  1. Anda tidak dapat melepaskan diri dari kutipan tunggal dalam string yang dikutip dengan kutipan tunggal. Jadi, Anda harus menutup kutipan, menambahkan kutipan lolos, lalu buka kutipan lagi. Yaitu 'foo'\''bar':, yang terurai sebagai:

    • 'foo'        dikutip foo
    • \'             melarikan diri '
    • 'bar'        dikutip bar

    menghasilkan foo'bar.

  2. (opsional) Anda tidak harus menggunakan /sed. Saya menemukan bahwa menggunakan /dan \dalam ekspresi sed yang sama membuatnya sulit dibaca.

Misalnya, untuk menghapus tanda kutip dari file ini:

$ cat /tmp/f
aaa"bbb"'ccc'aaa

Dengan dua tip saya di atas, perintah yang dapat Anda gunakan untuk menghapus tanda kutip ganda dan tunggal adalah:

$ sed -e 's|["'\'']||g'  /tmp/f

Berdasarkan tip pertama saya, shell mengurangi argumen sed kedua (yaitu, string setelah -e) ke s|["']||gdan meneruskan string itu ke sed. Berdasarkan tip kedua saya, sed memperlakukan ini sama dengan s/['"]//g. Itu berarti

hapus semua karakter yang cocok dengan salah satu 'atau "   (mis., ganti dengan yang tidak ada)

Anda mungkin memerlukan sesuatu yang lebih kompleks dari ini untuk melakukan apa yang Anda inginkan, tetapi ini adalah permulaan.

Yves Junqueira
sumber
1
Untuk menempatkan poin yang lebih baik pada tip kedua Anda: Anda dapat menggunakan karakter apa saja di tempat / saat menggunakan perintah s dan y, mungkin antara lain. Saat menggunakan regexps dengan perintah sed lainnya, pembatas pertama (jika menggunakan alternatif ke /) harus diloloskan. Pembatas pilihan Anda juga harus lolos jika Anda mencoba mencocokkannya dalam regexp.
Eli Heady
Sulit untuk menggabungkan tanda kutip tunggal dan ganda tanpa menjadi berantakan. Beberapa orang merasa lebih mudah dibaca jika Anda mengutip tanda kutip tunggal, dengan menempatkannya dalam tanda kutip ganda, daripada menghindarinya. Jadi, daripada 'foo'\''bar'kita gunakan 'foo'"'"'bar'.
Scott
1

Saya memiliki port Windows utilitas unix sehingga perintah terlihat sedikit berbeda tapi saya punya file csv dengan koma dan tanda kutip. Dengan menggunakan utas ini sebagai panduan, saya dapat menghapus tanda kutip melalui perintah ini:

c:\Temp> cat report.csv | sed "s/\,/\ /g" | sed "s/[""]//g"
JaimeR744
sumber
Terima kasih! terjebak pada ini!
sendbits