Usuń do pierwszego wystąpienia okrężnicy za pomocą sed


16

Moje sed to:

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

To musi wrócić,

bcde:cdeaf

(tj.) wszystkie znaki przed pierwszym dwukropkiem w linii i sam dwukropek muszą zostać usunięte.

Ale to niczego nie usuwa.

Moje zamieszanie powstaje głównie z powodu

1) Czy pareny do dopasowywania wzorów muszą być usuwane w wyrażeniach regularnych sed?

2) W obu przypadkach (z ucieczką / bez ucieczki), to nie działa. Próbowałem,

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

1
chcesz sed 's/[^:]*://'. I nie masz deleting linię wejściową, nawiasem mówiąc, jesteś modyfikując go z s///polecenia ubstitution. Musisz zastąpić pierwszy bit, który nie jest dwukropkiem, i dwukropek, który za nim podąża, niczym.
mikeserv

rozwiązuje to ... dzięki, stary ... to jest przykład, który nauczyłem się uczyć dopasowywania

3
Lub po prostu używając bash: printf "%s\n" "${line#*:}"...
jasonwryan

1
@jasonwryan - dobry punkt, biorąc pod uwagę przykładowe źródło. to zdecydowanie bardziej wydajny sposób na poradzenie sobie z tym. ale jeśli while read linejest taki $line, prawdopodobnie sedpowinien być preferowany.
mikeserv

Odpowiedzi:


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

Pierwszy ^oznacza początek linii. To [^:]tylko jedyny sposób, w jaki umiem pisać dwukropek . *Po dwukropku oznacza dowolną liczbę rzeczy tuż przed sobą (w tym przypadku nie-jelita grubego). Wreszcie :wybiera dwukropek.

Innymi słowy, wybierz początek linii, dowolną liczbę rzeczy, które nie są dwukropkiem, i pierwszy dwukropek.

Te //gśrodki usunięcie każdego dopasowanego instancji.


3
nie musisz ^zakotwiczać meczu, chyba że dodajesz również gflagę lobal. może istnieć tylko jedno pierwsze wystąpienie wzoru, a zatem gflaga lobal nie usuwa wszystkich [^:]*:wzorów z linii, tak jak gdyby nie ^zakotwiczenie go. zamiast komplikować wyrażenie regularne dwoma niepotrzebnymi flagami, które służą tylko do równoważenia siebie, możesz po prostu je pominąć, co pokazała edytowana wersja tej odpowiedzi przed jej wycofaniem. dlaczego nalegasz na rozpowszechnianie złych informacji, których nie znam, ale czyni to złą odpowiedź.
mikeserv

@mikeserv, jak już powiedziałem, dziękuję za zwrócenie na to uwagi. Szczerze doceniam, że pomagasz mi doskonalić swoje sedumiejętności. Jestem nowy sedi jeszcze nie czuję się komfortowo odchodząc od bardzo ograniczonej składni, którą do tej pory podjąłem. To sed(heh), myślę, że moja odpowiedź rozwiązuje problem OP, chociaż nie jest to optymalna (tj. Twoja) odpowiedź. To jest Stack Exchange, a nie Wikipedia, więc popraw mnie, jeśli się mylę, ale jeśli znasz lepszą odpowiedź, powinieneś ją opublikować, aby ludzie mogli zobaczyć różne podejścia i porównać je. Proszę nie przekształcać mojej odpowiedzi w swoją odpowiedź za pomocą funkcji edycji .
user1717828,

4
to nie była moja odpowiedź. to była twoja odpowiedź, zredagowana. to wszystko. i było dobrze . to już nie jest.
mikeserv

4

Do pracy z kolumnami służą cut:

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

tak samo

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

I inna wersja z sed(szybsze dla dużych zbiorów danych):

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

I raczej egzotyczne w bash

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

lub

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

lub

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

Możesz również dodać właściwy sposób, aby to zrobić za pomocą sed, to znaczysed 's/[^:]*://'
don_crissti

@don_crissti Wersja jest podana w odpowiedzi powyżej. Dodatkowo ze względu na użycie wyrażenia regularnego jest wolniejsze, ponieważ musi kompilować wyrażenie w każdej linii.
Costas

Nie, nie jest. Powyższa odpowiedź jest do bani i zasługuje na wiele pochlebnych opinii - zwłaszcza jeśli czytasz tam poprawki i komentarze.
don_crissti
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.