Załóżmy, że mam ciąg „abbc” i chcę zastąpić:
- ab -> bc
- bc -> ab
Jeśli spróbuję dwóch zamień, wynik nie jest tym, czego chcę:
echo 'abbc' | sed 's/ab/bc/g;s/bc/ab/g'
abab
Więc jakiej komendy sed mogę użyć do zamiany, jak poniżej?
echo abbc | sed SED_COMMAND
bcab
EDYCJA : W rzeczywistości tekst może mieć więcej niż 2 wzory i nie wiem, ile będzie potrzebnych zamienników. Ponieważ pojawiła się odpowiedź mówiąca, że sed
jest to edytor strumieniowy, a jego zamienniki są zachłannie, myślę, że będę musiał do tego użyć jakiegoś języka skryptowego.
g
flagę z obu tychs///
poleceń i to zadziała.ab
lub dlabc
niegoOdpowiedzi:
Może coś takiego:
Zamień
~
na znak, o którym wiesz, że nie będzie go w ciągu.źródło
\x0
do~~
.g
konieczne i co to robi?g
jest globalny - zastępuje wszystkie wystąpienia wzorca w każdej linii, a nie tylko pierwszy (co jest zachowaniem domyślnym).Zawsze używam wielu instrukcji z „-e”
$ sed -e 's:AND:\n&:g' -e 's:GROUP BY:\n&:g' -e 's:UNION:\n&:g' -e 's:FROM:\n&:g' file > readable.sql
Spowoduje to dodanie „\ n” przed wszystkimi AND, GROUP BY, UNION i FROM, podczas gdy „&” oznacza dopasowany ciąg, a „\ n &” oznacza, że chcesz zastąpić dopasowany ciąg „\ n” przed „dopasowanym” „
źródło
Oto odmiana odpowiedzi ooga, która działa w przypadku wielokrotnego wyszukiwania i zamiany par bez konieczności sprawdzania, w jaki sposób wartości mogą być ponownie użyte:
Oto przykład:
przed:
po:
Zauważ, że
\b
oznacza granice słów, co zapobiega________
ingerowaniu w wyszukiwanie (używam GNU sed 4.2.2 na Ubuntu). Jeśli nie używasz wyszukiwania granicy słów, ta technika może nie działać.Zauważ też, że daje to takie same wyniki jak usunięcie
s/________//g
i dopisanie&& sed -i 's/________//g' path_to_your_files/*.txt
na końcu polecenia, ale nie wymaga dwukrotnego podania ścieżki.Ogólną odmianą tego byłoby użycie
\x0
lub_\x0_
zamiast tego,________
jeśli wiesz, że w twoich plikach nie ma żadnych zer , jak sugerował jthill .źródło
sed 's/ab/xy/' | sed 's/cd/ab/' .....
sed
jest edytorem strumieniowym. Chciwie wyszukuje i zastępuje. Jedynym sposobem na zrobienie tego, o co prosiłeś, jest użycie pośredniego wzorca podstawienia i zmiana go z powrotem na końcu.echo 'abcd' | sed -e 's/ab/xy/;s/cd/ab/;s/xy/cd/'
źródło
Może to działać dla ciebie (GNU sed):
Używa to tabeli odnośników, która jest przygotowywana i trzymana w przestrzeni wstrzymania (HS), a następnie dołączana do każdej linii. Unikalny znacznik (w tym przypadku
\n
) jest dodawany na początku linii i stosowany jako metoda przewijania wyszukiwania wzdłuż całej linii. Gdy znacznik dotrze do końca linii, proces jest zakończony i drukowana jest tablica przeglądowa i odrzucane znaczniki.Uwaga: Tablica odnośników jest przygotowana na samym początku, a drugi unikatowy znacznik (w tym przypadku
:
) jest wybierany, aby nie kolidował z ciągami podstawień.Z kilkoma komentarzami:
Tabela działa w następujący sposób:
źródło
Może być prostsze podejście do wystąpienia pojedynczego wzorca, który możesz wypróbować w następujący sposób: echo 'abbc' | sed 's / ab / bc /; s / bc / ab / 2'
Moja produkcja:
W przypadku wielu wystąpień wzoru:
Przykład
Mam nadzieję że to pomoże !!
źródło
Tcl ma wbudowane do tego celu
Działa to poprzez chodzenie po łańcuchu po znaku, dokonując porównań łańcucha, zaczynając od bieżącej pozycji.
W perlu:
źródło
Oto
awk
oparty na oogassed
źródło