Ze standardową sed, będzie nigdy zobaczyć nowego wiersza w tekście odczytać z pliku. Jest tak, ponieważ sedczyta wiersz po wierszu, dlatego nie ma nowej linii na końcu tekstu bieżącej linii w obszarze sedwzorów. Innymi słowy, sedczyta dane rozdzielane znakiem nowej linii, a separatory nie są częścią tego, co sedwidzi skrypt.
Wyrażenia regularne można zakotwiczać na końcu wiersza za pomocą $(lub na początku za pomocą ^). Zakotwiczenie wyrażenia na początku / końcu linii wymusza dopasowanie dokładnie tam, a nie tylko w dowolnym miejscu linii.
Jeśli chcesz zamienić coś pasujące do wzoru [A-Za-z]*na końcu linii na coś, a następnie zakotwicz wzór w następujący sposób:
[A-Za-z]*$
... wymusi dopasowanie na końcu linii i nigdzie indziej.
Ponieważ jednak [A-Za-z]*$również nic nie pasuje (na przykład pusty ciąg obecny na końcu każdej linii), musisz wymusić dopasowanie czegoś , np. Poprzez określenie
[A-Za-z][A-Za-z]*$
lub
[A-Za-z]\{1,\}$
Zatem twoja linia poleceń sed będzie w ten sposób
$ sed 's/[A-Za-z]\{1,\}$/replace/' file.txt
Nie użyłem -Etutaj przełącznika, ponieważ nie jest potrzebny. Dzięki temu mógłbyś napisać
Komentarze nie są przeznaczone do rozszerzonej dyskusji; ta rozmowa została przeniesiona do czatu .
Kusalananda
3
sed "s/[a-zA-Z]*$/replace/" input.txt > result.txt
Lub długi złożony niepotrzebny sposób:
Dowiedziałem się, że można to zrobić, nadal używając sed, za pomocą tr. Możesz przypisać inny znak reprezentujący koniec linii. Należy użyć innej postaci tymczasowej, w tym przypadku „”. Użyjmy „~” do przedstawienia końca linii:
Nie jestem pewien, czy rozumiem ... Dlaczego po prostu nie zakotwiczysz do końca linii $? np.s/[a-zA-Z]*$/replace/
don_crissti
1
2 punkty: 1) Lepiej użyj \+zamiast, *ponieważ ta ostatnia dopuszcza zero liter na końcu łańcucha; 2) Możesz użyć klasy postaci [[:alpha:]]. Więc:sed 's/[[:alpha:]]\+$/replace/' file
glenn jackman
@glennjackman Po co jest ukośnik odwrotny przed plusem? Czy to nie pasuje do postaci dodatkowej?
Z (złamanego) fragmentu kodu, który opublikowałeś, wydaje się, że chcesz również zastąpić nowy wiersz. W takim przypadku samo zakotwiczenie wyrażenia regularnego nie może ci pomóc. Oto rozwiązanie:
sed '/[[:alpha:]]\+$/{N;s/[[:alpha:]]\+\n/replace/}' your_file
Zepsuty:
/[a-zA-Z]\+$/{} oznacza zastosowanie wszystkiego, co wchodzi w curlies, do linii pasujących do wyrażenia regularnego.
Wewnątrz curlies Noznacza „dołącz następną linię do aktywnego bufora” (co sednazywa „przestrzenią wzorów”)
Wreszcie s///oświadczenie jest wymaganą substytucją. Teraz działa, ponieważ przestrzeń wzorów zawiera dwie kolejne linie, a zatem nowa linia jest jej częścią.
Lub długi złożony niepotrzebny sposób:
źródło
$
? np.s/[a-zA-Z]*$/replace/
\+
zamiast,*
ponieważ ta ostatnia dopuszcza zero liter na końcu łańcucha; 2) Możesz użyć klasy postaci[[:alpha:]]
. Więc:sed 's/[[:alpha:]]\+$/replace/' file
-r
opcji używa tej składni wyrażeń regularnych .Z (złamanego) fragmentu kodu, który opublikowałeś, wydaje się, że chcesz również zastąpić nowy wiersz. W takim przypadku samo zakotwiczenie wyrażenia regularnego nie może ci pomóc. Oto rozwiązanie:
Zepsuty:
/[a-zA-Z]\+$/{}
oznacza zastosowanie wszystkiego, co wchodzi w curlies, do linii pasujących do wyrażenia regularnego.N
oznacza „dołącz następną linię do aktywnego bufora” (cosed
nazywa „przestrzenią wzorów”)s///
oświadczenie jest wymaganą substytucją. Teraz działa, ponieważ przestrzeń wzorów zawiera dwie kolejne linie, a zatem nowa linia jest jej częścią.źródło
Aby znaleźć koniec linii, użyj znaku $ :
Bez kotwicy na końcu linii:
Bez kotwicy na końcu linii:
źródło