Mengganti kejadian pertama dari suatu pola dalam satu baris, untuk semua baris dalam file dengan sed

16

Apakah mungkin melakukannya dalam satu liner?

Saya memiliki output seperti ini:

"First line" - Description  
" Second line" - Description  
"Third line" - Description  
" Fourth line" - Description  

Input ini dihasilkan secara otomatis.

Saya ingin mengganti kemunculan pertama "(tanda kutip + spasi) dengan "(tanda kutip) untuk setiap baris. Jika saya menerapkan substitusi secara global, itu juga akan mengubah setiap kejadian line" -menjadi line"-, jadi saya bertanya-tanya apakah mungkin menggunakan sed one liner untuk melakukannya.

Saya sudah mencoba menggunakan ^seperti ini

sed -r ':a;N;$!ba;s/(\^\" )/\"/g'

Tapi itu tidak berfungsi, itu tidak menggantikan apa pun. Saya mencoba

sed -r ':a;N;$!ba;s/(^|\" )/\"/g'

dan itu menggantikan semua kejadian. Saya baru saja mulai menggunakan sed, jadi saya tidak benar-benar tahu jika saya melakukan sesuatu yang salah.

Apa yang kulewatkan di sini?

Steve B.
sumber
Catatan tentang label: Perintah yang Anda tulis di atas dapat berfungsi dalam beberapa implementasi sed, tetapi untuk portabilitas dan untuk menghindari kesalahan yang sangat aneh, Anda harus mengakhiri argumen perintah yang diberikan setelah label (jika Anda memerlukannya sama sekali). Misalnya,sed -e ':a' -e 'N;$!ba' -e 'whatever'
Wildcard

Jawaban:

34

Anda terlalu memikirkannya. sedhanya mengganti instance pertama pada sebuah baris secara default (tanpa /gpengubah), meskipun Anda masih ingin berlabuh karena Anda tidak; sangat ingin instance pertama dalam baris sebagai yang di awal baris; dan Anda biasanya tidak memerlukan tindakan garis eksplisit yang Anda coba gunakan (mengapa?).

sed 's/^" /"/'
geekosaurus
sumber
Terima kasih! Saya pikir itu perlu untuk secara eksplisit menyatakan tindakan garis ketika bekerja pada file, membaca tentang hal itu dan terus menggunakannya. Saya benar-benar terlalu memikirkannya, itu tidak bisa lebih sederhana dan itu berhasil :)
Steve B.
Saya tergoda untuk mengatakan bahwa perintah-perintah itu sudah cukup usang; adalah mungkin untuk melakukan hal-hal multiline yang cukup rumit dengan mereka, tetapi tidak mudah untuk melakukannya dan hari ini Anda benar-benar lebih baik menggunakan perl / python / ruby ​​/ apa pun sebagai gantinya.
geekosaur
Sepenuhnya tidak setuju dengan komentar di atas; multisaluran sedperintah seperti Ndan label seperti :atidak usang sama sekali dan mereka yang portabel dan POSIX ditentukan , tidak seperti Perl / Python / Ruby / apapun. Namun benar bahwa jika Anda sering membutuhkannya , Anda harus belajarawk .
Wildcard
2

Jawaban yang lebih umum, karena saya tidak dapat mengomentari jawaban geekosaur - Anda tidak akan menaruh ^ (awal jangkar baris). Misalnya, jika Anda ingin mengganti kemunculan pertama A dengan B, Anda harus melakukannya

sed 's/A/B/'
spektrum
sumber