Poniższe wypisze dopasowanie linii TERMINATE
do końca pliku:
sed -n -e '/TERMINATE/,$p'
Wyjaśnione: -n
wyłącza domyślne zachowanie sed
drukowania każdej linii po wykonaniu na niej skryptu, -e
wskazany skrypt sed
, /TERMINATE/,$
to wybór zakresu adresów (linii), co oznacza, że pierwsza linia pasuje do TERMINATE
wyrażenia regularnego (jak grep) do końca pliku ( $
) , i p
jest poleceniem drukowania, które drukuje bieżący wiersz.
Spowoduje to wydrukowanie z linii, która następuje po dopasowaniu linii TERMINATE
do końca pliku:
(od PO dopasowaniu linii do EOF, NIE włączając pasującej linii)
sed -e '1,/TERMINATE/d'
Wyjaśnione: 1,/TERMINATE/
to wybór zakresu adresów (linii), co oznacza pierwszą linię wejścia do pierwszej linii pasującej do TERMINATE
wyrażenia regularnego, i d
jest to polecenie usuwania, które usuwa bieżącą linię i przeskakuje do następnej. Jako sed
domyślne zachowanie jest drukowanie linii, zostanie wydrukowana po linie TERMINATE
na końcu wejścia.
Edytować:
Jeśli chcesz mieć wiersze przed TERMINATE
:
sed -e '/TERMINATE/,$d'
A jeśli chcesz, aby obie linie przed i po TERMINATE
w 2 różnych plikach w jednym przebiegu:
sed -e '1,/TERMINATE/w before
/TERMINATE/,$w after' file
Pliki przed i po będą zawierały linię z zakończeniem, więc aby przetworzyć każdy, musisz użyć:
head -n -1 before
tail -n +2 after
Edit2:
JEŚLI nie chcesz na stałe zakodować nazw plików w skrypcie sed, możesz:
before=before.txt
after=after.txt
sed -e "1,/TERMINATE/w $before
/TERMINATE/,\$w $after" file
Ale wtedy musisz pominąć $
znaczenie ostatniej linii, aby powłoka nie spróbowała rozwinąć $w
zmiennej (zwróć uwagę, że teraz używamy podwójnych cudzysłowów wokół skryptu zamiast pojedynczych cudzysłowów).
Zapomniałem powiedzieć, że nowa linia jest ważna po nazwach plików w skrypcie, aby sed wiedział, że nazwy plików się kończą.
Edycja: 2016-0530
Sébastien Clément zapytał: „Jak zamienić zakodowane na stałe TERMINATE
zmienną?”
Utworzyłbyś zmienną dla pasującego tekstu, a następnie zrobiłbyś to w taki sam sposób, jak w poprzednim przykładzie:
matchtext=TERMINATE
before=before.txt
after=after.txt
sed -e "1,/$matchtext/w $before
/$matchtext/,\$w $after" file
aby użyć zmiennej dla pasującego tekstu z poprzednich przykładów:
## Print the line containing the matching text, till the end of the file:
## (from the matching line to EOF, including the matching line)
matchtext=TERMINATE
sed -n -e "/$matchtext/,\$p"
## Print from the line that follows the line containing the
## matching text, till the end of the file:
## (from AFTER the matching line to EOF, NOT including the matching line)
matchtext=TERMINATE
sed -e "1,/$matchtext/d"
## Print all the lines before the line containing the matching text:
## (from line-1 to BEFORE the matching line, NOT including the matching line)
matchtext=TERMINATE
sed -e "/$matchtext/,\$d"
Ważne punkty dotyczące zastępowania tekstu zmiennymi w takich przypadkach to:
- Zmienne (
$variablename
) zawarte w single quotes
[ '
] nie "rozszerzają się", ale zmienne wewnątrz double quotes
[ "
] tak. Więc trzeba zmienić wszystko single quotes
, aby double quotes
jeśli zawierają tekst, który chcesz zastąpić zmienną.
- Te
sed
zakresy zawierają również $
i natychmiast następuje listem jak: $p
, $d
, $w
. Będą one również wyglądać zmiennych zostać rozszerzona, więc trzeba uciekać te $
znaki z backslashem [ \
], takich jak: \$p
, \$d
, \$w
.
grep 'TERMINATE' file