2012-09-27 13 views
5

Chciałbym zamienić wszystkie {} na pewną linię na [], ale niestety mogę tylko dopasować ostatnie wystąpienie wyrażeń regularnych.sed tylko zastępując ostatnie wystąpienie meczu - trzeba dopasować wszystkie

Mam plik konfiguracyjny, który ma strukturę następująco:

entry { 
    id  123456789 
    desc This is a description of {foo} and was added by {bar} 
    trigger 987654321 
} 

Mam następujący sed, które jest w stanie zastąpić ostatni mecz „bar”, ale nie „foo”:

sed s'/\(desc.*\){\(.*\)}/\1\[\2\]/g' < filename 

Zakotwiczę to wyszukiwanie do wiersza zawierającego "desc", ponieważ nie chciałbym, aby zastąpiło ono nawiasy klamrowe każdego bloku "wpisu".

Dla mojego życia nie jestem w stanie wymyślić sposobu zastąpienia wszystkich wystąpień.

Każda pomoc jest doceniana - uczy się przez cały dzień i nie jest w stanie przeczytać więcej tutoriali z obawy przed pęknięciem rogówki.

Dzięki!

Odpowiedz

4

Spróbuj wykonać następujące czynności:

sed '/desc/ s/{\([^}]*\)}/[\1]/g' filename 

wyszukiwania i zamiany w powyższym poleceniu zostanie wykonane tylko dla linii pasujących regex /desc/, jednak nie sądzę, jest to rzeczywiście konieczne, ponieważ tekst sed Przetwarza po linii, więc nawet bez tego nie zastępowałbyś nawiasów klamrowych w bloku 'entry'. Oznacza to, że prawdopodobnie można to uprościć do następującej:

sed 's/{\([^}]*\)}/[\1]/g' filename 

Zamiast .* wewnątrz grupy przechwytywania [^}]* używanej który będzie pasował wszystko wyjątkiem zamykających szelkami, w ten sposób, że nie będzie pasował od pierwszego otwarcie do ostatniego zamknięcia.

Można również podać nazwę pliku jako ostateczny argument dla sed, zamiast korzystać z przekierowania wejścia.

+0

Dziękuję F.J, że działało świetnie! (PS - może oznaczać jako odpowiedział w 3 minuty najwyraźniej :-) – halfpasthope

Powiązane problemy