Patrzyłem na to pytanie, a potem zastanawiałem się, jak zaimplementować moją odpowiedź, która używa
sed
wyłącznie
POSIX
ex
.
Sztuczka polega na tym, że chociaż sed
mogę porównać przestrzeń wstrzymania z przestrzenią wzorów, aby sprawdzić, czy są one dokładnie równoważne (z
G;/^\(.*\)\n\1$/{do something}
), nie znam sposobu na wykonanie takiego testu ex
.
Wiem, że w Vimie mogłem Y
obrócić pierwszą linię, a następnie napisać,
:2,$g/<C-r>0/d
by prawie zrobić to, co określam - ale jeśli pierwszy wiersz zawiera cokolwiek innego niż bardzo prosty tekst alfanumeryczny, staje się to rzeczywiście przypadkiem, ponieważ linia jest zrzucana jako
wyrażenie regularne , nie tylko ciąg znaków do porównania. (A jeśli pierwszy wiersz zawiera ukośnik, reszta wiersza zostanie zinterpretowana jako polecenie!)
Więc jeśli chcę usunąć wszystkie wiersze, myfile
które są identyczne z pierwszym wierszem - ale nie usunąć pierwszego - jak mogę to zrobić za pomocą ex
? Jeśli o to chodzi, jak mogę to zrobić za pomocą vi
?
Czy istnieje sposób POSIX na usunięcie linii, jeśli dokładnie pasuje do innej linii?
Być może coś w rodzaju tej wymyślonej składni:
:2,$g/**lines equal to "0**/d
<C-r>0
bardzo dobre. Nie jestem pewien, czy lepiej radzisz sobie tylko z poleceniami Ex, ponieważ musisz chronić znaki specjalne. Bez ograniczenia zgodnego z POSIX myślę, że użyłbyś bardzo nomagicznego przełącznika, \V
a następnie chroniłbyś odwrotny ukośnik (ponieważ zachowuje on swoje specjalne znaczenie nawet przy pomocy \V
) za pomocą escape()
funkcji, której drugi argument jest ciągiem zawierającym wszystkie znaki, które chcesz uciec / zabezpieczyć .
:execute '2,$g/\V' . escape(getline(1), '\/') . '/d'
Lub możesz użyć innego znaku dla separatora wzorców, takiego jak średnik. W takim przypadku nie trzeba chronić ukośnika we wzorcu. Dałoby to coś takiego::execute '2,$g;\V' . escape(getline(1), '\') . ';d'
sed
również bardzo dobre. Dzięki Vimowi często przekazujesz określone zadania specjalne innym programom i sed
prawdopodobnie jest to dobry przykład. Nawiasem mówiąc, nie musisz uruchamiać sed
całego bufora. Jeśli chcesz uruchomić go tylko na części bufora, możesz podać zakres. Na przykład, jeśli chcesz filtrować tylko te linie pomiędzy 50 a 100, można wpisać: :50,100!<your sed command>
.
:execute '2,$g/\V' . escape(getline(1), '\') . '/d'