Mengganti titik (.) Dalam sed

9

Jadi pertanyaan sebenarnya adalah - apakah ada yang punya ide bagaimana menghapus M-BM-karakter khusus tanpa risiko kehilangan karakter lain?

Saya memiliki serangkaian teks:

" . . ."

itu adalah

space dot space dot space dot

Saya mencoba mengganti semua kemunculan string ini dalam file teks

"..."

itu adalah

dot dot dot

Saya coba lakukan dengan sed:

sed -r 's:\s\.\s\.\s\.:...:g' -i sed-dots

Sayangnya, itu tidak mengubah file input sedikit pun. File: https://www.dropbox.com/s/46zmiruy3ln85a1/sed-dots

Ketika saya mencoba untuk mengganti string yang sama di editor teks (saya menggunakan geany) itu ditemukan dan diganti dengan benar.

Satu-satunya alasan yang dapat saya pikirkan adalah bahwa beberapa (atau semua) ruang itu bukan benar-benar ruang, tetapi beberapa karakter khusus.

Adakah yang tahu cara menemukan dan mengganti string itu dengan sed (atau alat baris perintah lainnya)? Silakan uji ide Anda pada file saya, karena masalahnya tidak sejelas kelihatannya - ini sebabnya saya bertanya tentangnya.

Setelah menggunakan cat -Amyfile, sepertinya masalah bukan spasi, melainkan M-BM-karakter khusus. Menggunakan simbol apa pun yang .disarankan untuk pencarian bukanlah ide yang baik karena ada risiko beberapa karakter lain akan dihapus.

Rafal
sumber

Jawaban:

9

Pertama saya akan mulai dengan menguji dengan echodan mem-pipkannya ke dalam sed, daripada menggunakan file nyata. Kedua, Anda bisa menggunakan a {n}dalam model regex yang diperluas untuk menunjukkan kelipatan dan batas.

Anda cukup banyak di sana tetapi regex Anda mengharapkan ruang terdepan.

$ echo 'cheese . . . muffins' | sed -r 's/(\s?\.){3}/ dot dot dot/g'
cheese dot dot dot muffins

Perhatikan \s?masih cukup serakah untuk merusak output, jadi saya telah menambahkan spasi ke output. Anda mungkin tidak menginginkan itu. Saya juga telah membuat ruang opsional, jadi itu akan cocok dengan semua yang berikut:

...
. ..
.. .
. . .
 . . . 

Hapus saja ?flag opsional .


Mengingat masalah Anda dengan unicode (dalam komentar), Anda dapat memaksa data ke ASCII yang setara dengan iconvdan kemudian sed:

$ iconv -f utf-8 -t ascii//translit sed-dots | sed -r 's/(\s?\.){3}/ dot dot dot/g'
Lorem ipsum dot dot dot
Some dot dot dot more text
Oli
sumber
Saya terkejut bahwa Anda merekomendasikan untuk menggunakan echoalih-alih melakukan catting file, setidaknya ketika Anda menyimpan file, Anda tahu shellnya tidak menafsirkan apa-apa, dan juga tidak ada gema.
Flimm
@ Flimm untuk contoh sederhana dengan titik-titik, ini sebenarnya bukan masalah. Jika Anda akan memuat dari file, jangan repot-repot dengan cat- hanya sedmemuat file (sesuai contoh OP) tetapi jangan menyimpan inline (hapus -i, sehingga Anda dapat melihat dan menguji terhadap output).
Oli
@ Oli Ini berfungsi dengan contoh Anda, tetapi tidak bekerja dengan file saya (dalam pertanyaan saya, ada tautan). Itu masalah - perintah Anda dan orang lain harus bekerja, tetapi mereka tidak melakukannya karena ada beberapa masalah dengan titik-titik itu. Silakan uji perintah Anda pada file saya dan Anda akan melihat bahwa itu tidak berfungsi.
Rafal
1
@Rafal Jika Anda melihat, cat -A sed-dotsAnda dapat melihat bahwa "spasi" antara titik-titik adalah M-BM- karakter khusus ... Tidak yakin bagaimana mereka merayap di sana tetapi mereka perlu diganti. Jika Anda tidak dapat menargetkan mereka dengan baik, ini berfungsi: sed -r 's/(\s\..\..\.)/ dot dot dot/ig' sed-dots
Oli
@ Oli Berhasil. Terima kasih banyak! Bisakah Anda menjelaskan sintaksisnya? Apakah Anda yakin itu tidak memiliki efek samping dan tidak akan menggantikan yang lain? Sejauh yang saya lihat, RegExp ini akan cocok dengan karakter apa pun setelah titik. Namun, M-BM bukan satu karakter, itu tiga. Jadi, bagaimana mungkin itu bekerja?
Rafal
0

Coba yang berikut ini untuk mengganti semua "." Ke "."

sed -r 's/\. /\./g' -i sed-dots

Tapi untuk ". . ." untuk "..."

sed -r 's/\. \. \./\.\.\./g' -i sed-dots
Meer Borg
sumber
0

Saya dapat menggunakan file Anda ketika saya menjalankannya:

tr '\240' ' ' < sed-dots.txt > sed-dots.new

Ini berfungsi tanpa langkah konversi:

sed 's/[[:blank:]]\.[[:blank:]]\.[[:blank:]]\./.../g' sed-dots.txt
Pengamat
sumber
Tidak bekerja. Saya kira alasannya adalah karakter M-BM aneh yang @Oli temukan.
Rafal