Hapus sampai kemunculan pertama usus menggunakan sed

16

Perintah sed saya adalah,

 sed '/(.*:)/d' <<< 'abcd:bcde:cdeaf'

Itu harus kembali,

bcde:cdeaf

(Yaitu) semua karakter sebelum titik dua pertama di baris dan titik dua itu sendiri harus dihapus.

Tapi ini tidak menghapus apa pun.

Kebingungan saya muncul terutama karena,

1) Apakah orangtua untuk pencocokan pola harus melarikan diri di dalam regex-es?

2) Dalam kedua kasus (dengan melarikan diri / tanpa escpaing), itu tidak berfungsi. Saya mencoba,

sed -E '/\\(.*:\\)/d' <<< 'abcd:bcde'

sumber
1
kamu mau sed 's/[^:]*://'. Dan Anda tidak dmenghapus jalur input, omong-omong, Anda memodifikasinya dengan s///perintah ubstitusi. Anda harus mengganti bit pertama yang bukan titik dua dan titik dua yang mengikutinya tanpa apa-apa.
mikeserv
yang menyelesaikannya ... terima kasih, bung ... ini adalah contoh yang saya ambil untuk mempelajari pencocokan pola regex di dalam ... jadi, saya mencari jawaban yang menggunakan pencocokan grup / pola dengan parens ...
3
Atau, hanya menggunakan bash: printf "%s\n" "${line#*:}"...
jasonwryan
1
@jasonwryan - bagus, mengingat contoh sumber. ini jelas cara yang lebih efisien untuk menanganinya. tetapi jika itu while read lineyang mendapat $line, mungkin sedharus lebih disukai.
mikeserv

Jawaban:

23
$ echo 'abcd:bcde:cdeaf' | sed 's/^[^:]*://g'
bcde:cdeaf

Yang pertama ^berarti awal dari garis. Ini [^:]satu-satunya cara saya tahu bagaimana menulis bukan titik dua . Tanda *titik dua berarti sejumlah hal sebelum saya (dalam hal ini tanda titik dua). Akhirnya, :memilih usus besar.

Dengan kata lain, pilih awal baris, sejumlah hal yang bukan titik dua, dan titik dua pertama.

The //gberarti menghapus setiap contoh cocok.

pengguna1717828
sumber
3
Anda tidak perlu ^memasang gsaingan , kecuali karena Anda juga menambahkan bendera lobal. hanya akan pernah ada satu kemunculan pola yang pertama, sehingga gbendera lobal tidak menghapus semua [^:]*:pola dari suatu garis, seperti yang akan terjadi jika Anda tidak ^mengikatnya. alih-alih menyulitkan regex dengan dua bendera yang tidak perlu yang hanya berfungsi untuk mengacaukan satu sama lain, Anda bisa mengabaikannya, yang ditunjukkan oleh versi yang diedit dari jawaban ini sebelum Anda mengembalikannya. mengapa Anda bersikeras menyebarkan informasi buruk saya tidak tahu, tetapi ini membuat jawaban yang buruk.
mikeserv
@ mikeserv, seperti sudah saya katakan, terima kasih telah menunjukkan ini. Saya sangat menghargai Anda membantu saya meningkatkan sedketerampilan saya . Saya baru seddan belum nyaman menyimpang dari sintaks yang sangat terbatas yang saya ambil sejauh ini. Itu sed(heh), saya pikir jawaban saya memecahkan masalah OP meskipun itu bukan jawaban yang optimal (yaitu, Anda). Ini adalah Stack Exchange, bukan Wikipedia, jadi perbaiki saya jika saya salah, tetapi jika Anda tahu jawaban yang lebih baik Anda harus mempostingnya sehingga orang dapat melihat berbagai pendekatan dan membandingkannya. Tolong jangan mengubah jawaban saya menjadi jawaban Anda dengan fungsi edit .
user1717828
4
itu bukan jawaban saya. itu jawaban Anda, diedit. itu saja. dan itu bagus . tidak lagi.
mikeserv
4

Untuk beroperasi dengan kolom ada cut:

echo 'abcd:bcde:cdeaf' | cut -d: -f2-

sama saja

echo 'abcd:bcde:cdeaf' | cut -d: -f1 --complement

Dan versi lain dengan sed(lebih cepat untuk data besar):

echo 'abcd:bcde:cdeaf' | sed 's/^://;t;s/:/\n:/;D'

Dan agak eksotis di bash

echo 'abcd:bcde:cdeaf' | { IFS=: read -r first last ; echo "$last" ; }

atau

echo 'abcd:bcde:cdeaf' | { read -r line ; echo ${line#*:} ; }

atau

echo 'abcd:bcde:cdeaf' | { IFS=: read -a a ; printf '%b:' "${a[@]:1}\c" ; echo ;}
Costas
sumber
Anda juga dapat menambahkan cara yang tepat untuk melakukannya dengan sed, yaitused 's/[^:]*://'
don_crissti
@don_crissti Versi ini tercantum dalam jawaban di atas. Selain itu karena penggunaan regexp lebih lambat karena harus mengkompilasi ekspresi di setiap baris.
Costas
Tidak, tidak. Jawaban di atas menyebalkan waktu besar dan layak banyak downvotes - terutama jika Anda membaca revisi dan komentar di sana.
don_crissti