Sed kullanarak kolonun ilk oluşumuna kadar sil


16

Sed komutum,

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

Geri dönmeli,

bcde:cdeaf

(yani) satırdaki ilk kolondan önceki tüm karakterler ve iki nokta üst üste işaretinin kaldırılması gerekir.

Ama bu hiçbir şeyi kaldırmıyor.

Benim karışıklığım esas olarak,

1) Desen eşleşmesi için parenler sed regex-es içinden kaçmalı mı?

2) Her iki durumda da (kaçan / kaçan), nt çalışmıyor. Denedim,

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

1
istiyorsun sed 's/[^:]*://'. Ve dgiriş satırını silmiyorsunuz, bu arada, bir s///ikame komutuyla değiştiriyorsunuz . İlk kolon olmayan biti ve onu izleyen iki nokta üst üste hiçbir şey kullanmamalısınız.
mikeserv

çözer ... teşekkürler, adam ... bu sed içinde regex desen eşleştirme öğrenmek için aldı bir örnek ... yani, ben parens ile grup / desen eşleme kullanan bir cevap arıyorum ...

3
Veya, sadece bash kullanarak: printf "%s\n" "${line#*:}"...
jasonwryan

1
@jasonwryan - örnek kaynak göz önüne alındığında iyi bir nokta. bununla başa çıkmanın kesinlikle daha etkili bir yoludur. ama eğer bu bir while read linealırsa $line, muhtemelen sedtercih edilmelidir.
mikeserv

Yanıtlar:


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

Birincisi ^, çizginin başlangıcı anlamına gelir. İki nokta üst üste yazmamayı bilmemin[^:] tek yolu bu . Kolondan sonra, benden hemen önce herhangi bir sayıda şey (bu durumda kolon olmayan) anlamına gelir. Sonunda, iki nokta üst üste seçer.*:

Başka bir deyişle, satırın başlangıcını, iki nokta üst üste olmayan herhangi bir sayıyı ve ilk iki nokta üst üste seçin.

Bu //g, eşleşen her örneği siler.


3
lobal bir bayrak ^da eklemeniz dışında, gmaçınızı tutturmanıza gerek yoktur . bir desenin yalnızca bir kez gerçekleşmesi olabilir ve bu nedenle global bayrağı, [^:]*:bir çizgiden tüm desenleri çıkarmaz , eğer ^onu tutturmazsanız yaptığı gibi. Normal ifadeyi, yalnızca birbirini dengesiz hale getirmeye hizmet eden iki gereksiz bayrakla karmaşıklaştırmak yerine, onları dışarıda bırakabilirsiniz; neden bilmiyorum kötü bilgi yaymak ısrar ediyorsun, ama bu kötü bir cevap yapar.
mikeserv

@mikeserv, daha önce de söylediğim gibi, bunu işaret ettiğiniz için teşekkürler. sedBecerilerimi geliştirmeme yardımcı olduğun için içtenlikle teşekkür ederim . sedŞimdiye kadar aldığım çok sınırlı sözdiziminden yeni çıkıyorum ve henüz rahat değilim. Bu sed(heh), bence cevabım OP'nin problemini optimal (yani senin cevabın) olmasa bile çözüyor. Bu Yığın Değişimi, Wikipedia değil, bu yüzden yanlışsam beni düzeltin ama daha iyi bir cevap biliyorsanız, insanların çeşitli yaklaşımları görebilmeleri ve karşılaştırabilmeleri için bunu göndermelisiniz. Lütfen cevabımı düzenleme işleviyle cevabınıza çevirmeyin .
user1717828

4
bu benim cevabım değildi. cevabınız buydu, düzenlendi. bu kadar. ve iyiydi . artık değil.
mikeserv

4

Sütunlarla çalışmak için cut:

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

aynı şey

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

Ve diğer sürüm sed(büyük veri için daha hızlı):

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

Ve oldukça egzotik bash

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

veya

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

veya

echo 'abcd:bcde:cdeaf' | { IFS=: read -a a ; printf '%b:' "${a[@]:1}\c" ; echo ;}

Ayrıca sed ile yapmak için uygun yolu ekleyebilirsiniz, yanised 's/[^:]*://'
don_crissti

@don_crissti Sürüm yukarıdaki cevapta belirtilmiştir. Ayrıca regexp kullanımı nedeniyle her satırda ifade derlemek zorunda olduğu için daha yavaştır.
Costas

Hayır değil. Yukarıdaki cevap çok zaman alıyor ve özellikle revizyonları ve yorumları okuyorsanız, çok sayıda iniş vekilini hak ediyor.
don_crissti
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.