Jak zastąpić ostatnie wystąpienie znaku w ciągu za pomocą sed?

31

Jak zastąpić tylko ostatnie wystąpienie „-” w ciągu spacją przy użyciu sed ?

Na przykład:

echo $MASTER_DISK_RELEASE
swp-RedHat-Linux-OS-5.5.0.0-03

ale chcę uzyskać następujące dane wyjściowe (zastępując ostatni łącznik [„-”] spacją)

swp-RedHat-Linux-OS-5.5.0.0 03
maihabunash
źródło

Odpowiedzi:

48

Możesz to zrobić za pomocą singla sed:

sed 's/\(.*\)-/\1 /'

lub używając rozszerzonego wyrażenia regularnego:

sed -r 's/(.*)-/\1 /'

Chodzi o to, że sedjest bardzo chciwy, więc pasuje do jak największej liczby postaci -, w tym innych -.

$ echo 'swp-RedHat-Linux-OS-5.5.0.0-03' | sed 's/\(.*\)-/\1 /'
swp-RedHat-Linux-OS-5.5.0.0 03
jimmij
źródło
2
Uwaga: nie jest to przenośne. Niektóre wersje nie-GNU sednie obsługują dopasowania wzorca. W takim przypadku będziesz potrzebować czegoś innego, perl -pne 's/(.*)-/$1 /'czy to rozwiązania rozszerzenia parametrów @ Thora, czy czegoś innego.
Adam Katz,
oczywiście :-) dzięki ...
Greg
W przypadku korzystania z pojedynczych cudzysłowów nie powinno być potrzeby ucieczki od tych nawiasów.
jgmjgm
@jgmjgm Możesz pominąć ukośniki odwrotne, używając rozszerzonego wyrażenia regularnego z sed -r.
jimmij
1
@VinayPotluri Try sed -r 's/(.*)-(.*)-/\1 \2 /').
jimmij
27

Można to również obsłużyć dzięki rozszerzeniu parametrów bash :

s=swp-RedHat-Linux-OS-5.5.0.0-03
echo ${s%-*} ${s##*-}

Wydajność:

swp-RedHat-Linux-OS-5.5.0.0 03
Thor
źródło
Bardzo kreatywny, uwielbiam tę odpowiedź
dpritch
11

Coś takiego działało dla mnie, chociaż jestem pewien, że są lepsze sposoby

echo "swp-RedHat-Linux-OS-5.5.0.0-03" | rev | sed 's/-/ /' | rev
swp-RedHat-Linux-OS-5.5.0.0 03
Rahul
źródło
To jest złe ... po prostu złe. Dlaczego wykonujesz 4 operacje, skoro możesz zrobić 2?
Joshpbarron
7
Dla kogoś, kto tylko rozumie wyrażenia regularne, odpowiedzi te wydają się znacznie bardziej przystępne. I kogo obchodzi, ile to zajmie operacji, będzie to natychmiastowe we wszystkich praktycznych przypadkach. Zastanowiłbym się zatem nad czytelnością nad jakąkolwiek arbitralną regułą, aby użyć jak najmniejszej liczby operacji.
Psirus
5
@Psirus mam nadzieję, że to nie jest zamiar otworzyć puszkę Pandory, ale pomysł wykorzystania pomniejszych operacji jest pokazanie pewnego poziomu opanowania tych mniejszych operacji. Na przykład odpowiedź @ Thora pokazuje uznanie dla bashfunkcji rozszerzania parametrów, która działa dobrze, jeśli używa bashrównież OP . Będzie delikatna równowaga między czytelnością (do tego stopnia, że ​​jest bardzo gadatliwa) a korzystaniem z odpowiednich narzędzi, ale częściej niż przy użyciu odpowiednich narzędzi dominuje.
hjk