wprowadzenie
poleceniesed
, skrót od stream editor, wykonuje operacje edycyjne na tekście pochodzącym ze standardowego wejścia lub pliku. sed
edytuje wiersz po wierszu i w sposób nieinteraktywny.
oznacza to, że wszystkie decyzje edycyjne podejmujesz podczas wywoływania polecenia, ased
wykonuje polecenia automatycznie., Może to wydawać się mylące lub nieintuicyjne, ale jest to bardzo wydajny i szybki sposób przekształcania tekstu, szczególnie w ramach skryptu lub zautomatyzowanego przepływu pracy.
Ten samouczek obejmie kilka podstawowych operacji i wprowadzi cię w składnię wymaganą do obsługi tego edytora. Prawie na pewno nigdy nie zastąpisz zwykłego edytora tekstu sed
, ale prawdopodobnie stanie się on mile widzianym dodatkiem do twojego zestawu narzędzi do edycji tekstu.
Uwaga: Ten samouczek używa wersji GNUsed
znalezionej na Ubuntu i innych systemach operacyjnych Linux., Jeśli używasz macOS, będziesz mieć wersję BSD, która ma różne opcje i argumenty. Możesz zainstalować wersję GNU sed
z Homebrew używając brew install gnu-sed
.
podstawowe użycie
sed
działa na strumieniu tekstu, który odczytuje z pliku tekstowego lub ze standardowego wejścia (STDIN). Oznacza to, że możesz wysłać wyjście innego polecenia bezpośrednio do sed w celu edycji lub możesz pracować nad plikiem, który już utworzyłeś.,
należy również pamiętać, żesed
domyślnie wypisuje wszystko na standardowe wyjście (STDOUT). Oznacza to, że sed
, o ile nie zostanie przekierowany, wydrukuje swoje wyjście na ekran zamiast zapisać je w pliku.
podstawowe użycie to:
- sed commands
w tym samouczku użyjesz kopii licencji oprogramowania BSD do eksperymentowania z sed
., W systemie Ubuntu wykonaj następujące polecenia, aby skopiować plik licencji BSD do katalogu domowego, aby móc z nim pracować:
- cd
- cp /usr/share/common-licenses/BSD .
Jeśli nie masz lokalnej kopii licencji BSD, utwórz ją samodzielnie za pomocą tego polecenia:
- cat << 'EOF' > BSD
- Copyright (c) The Regents of the University of California.
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- EOF
użyjmy sed
aby wyświetlić zawartość pliku licencyjnego BSD. sed
domyślnie wysyła swoje wyniki na ekran, co oznacza, że można go używać jako czytnika plików, nie przekazując mu żadnych poleceń edycyjnych., Spróbuj wykonać następujące polecenie:
- sed '' BSD
zobaczysz licencję BSD wyświetloną na ekranie:
OutputCopyright (c) The Regents of the University of California.All rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditionsare met:1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.......
pojedyncze cudzysłowy zawierają polecenia edycji przekazywane dosed
. W tym przypadku przekazałeś go nic, więc sed
wypisał każdą odebraną linię na standardowe wyjście.
sed
może używać standardowego wejścia zamiast pliku., Przełącz wyjście polecenia cat
do sed
aby uzyskać ten sam wynik:
- cat BSD | sed ''
zobaczysz wyjście pliku:
OutputCopyright (c) The Regents of the University of California.All rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditionsare met:1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.. . .. . .
jak widać, możesz operować na plikach lub strumieniach tekstu, takich jak te wytwarzane podczas rurociągów wyjściowych ze znakiem (|)
, tak samo łatwo.
Drukowanie linii
w poprzednim przykładzie widać, że wejście przechodzące dosed
bez żadnych operacji wyświetla wyniki bezpośrednio na standardowe wyjście.,
przyjrzyjmy sięsed
’s explicitprint
polecenia, które można określić za pomocąp
znak w pojedynczych cudzysłowach.
wykonaj następujące polecenie:
- sed 'p' BSD
zobaczysz każdą linię BSD
plik wydrukowany dwukrotnie:
OutputCopyright (c) The Regents of the University of California.Copyright (c) The Regents of the University of California.All rights reserved.All rights reserved.Redistribution and use in source and binary forms, with or withoutRedistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditionsmodification, are permitted provided that the following conditionsare met:are met:. . .. . .
sed
automatycznie wypisuje każdą linię domyślnie, a następnie kazałeś jej wydrukować linie jawnie za pomocą polecenia „P”, więc każda linia zostanie wydrukowana dwa razy.,
Jeśli dokładnie przyjrzysz się wyjściu, zobaczysz, że ma dwa razy pierwszą linię, a następnie dwa razy drugą linię, itd., co mówi, że sed
działa na danych linia po linii. Odczytuje linię, operuje na niej i wypisuje wynikowy tekst przed powtórzeniem procesu w następnej linii.
możesz wyczyścić wyniki, przechodząc -n
do sed
, co wyłącza automatyczne drukowanie:
- sed -n 'p' BSD
OutputCopyright (c) The Regents of the University of California.All rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditionsare met:1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.. . .. . .
teraz są z powrotem do drukowania każdej linii raz.,
przykłady do tej pory nie można uznać za edytowanie (chyba, że chciałeś wydrukować każdą linię dwa razy…). Następnie dowiesz się, w jaki sposób sed
może modyfikować dane wyjściowe, kierując konkretne sekcje danych tekstowych.
Korzystanie z zakresów adresów
adresy pozwalają kierować określone części strumienia tekstowego. Możesz określić konkretną linię lub nawet zakres linii.
niechsed
wyświetli pierwszą linię pliku., Wykonaj następujące polecenie:
- sed -n '1p' BSD
pierwsza linia wyświetla się na ekranie:
OutputCopyright (c) The Regents of the University of California.
umieszczając numer 1
przed poleceniem drukowania powiedziałeś sed
div > numer linii do pracy na. Możesz równie łatwo wydrukować pięć linii (nie zapomnij”- n”):
- sed -n '1,5p' BSD
zobaczysz to wyjście:
OutputCopyright (c) The Regents of the University of California.All rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions
właśnie podałeś zakres adresów do sed
., Jeśli podasz sed
adres, będzie on wykonywał tylko polecenia, które następują po tych liniach. W tym przykładzie kazałeś sed wydrukować linie od 1 do 5. Można było określić to w inny sposób, podając pierwszy adres, a następnie używając offsetu, aby powiedzieć sed, ile dodatkowych linii ma podróżować, jak to:
- sed -n '1,+4p' BSD
spowoduje to to samo wyjście, ponieważ poleciłeś sed
aby rozpocząć od linii 1, a następnie działać na kolejnych 4 liniach, jak również.,
Jeśli chcesz wydrukować co drugą linię, podaj interwał po znaku~
. Poniższe polecenie wyświetla co drugi wiersz w pliku BSD
, zaczynając od linii 1:
- sed -n '1~2p' BSD
oto wyjście, które zobaczysz:
OutputCopyright (c) The Regents of the University of California.modification, are permitted provided that the following conditions1. Redistributions of source code must retain the above copyright2. Redistributions in binary form must reproduce the above copyright documentation and/or other materials provided with the distribution. may be used to endorse or promote products derived from this software. . .. . .
możesz użyć sed
, aby również usunąć tekst z wyjścia.,
usuwanie tekstu
można wykonać usuwanie tekstu tam, gdzie wcześniej określano drukowanie tekstu, zmieniając poleceniep
na polecenied
.
w tym przypadku nie potrzebujesz już polecenia -n
, ponieważ sed
wyświetli wszystko, co nie zostało usunięte. To pomoże Ci zobaczyć, co się dzieje.,
zmodyfikuj ostatnie polecenie z poprzedniej sekcji tak, aby
usunąć wszystkie pozostałe wiersze zaczynające się od pierwszej:
- sed '1~2d' BSD
rezultatem jest to, że widzisz każdą linię, której nie podałeś ostatnio:
OutputAll rights reserved.Redistribution and use in source and binary forms, with or withoutare met: notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer in the3. Neither the name of the University nor the names of its contributors without specific prior written permission.. . .. . .
ważne jest, aby pamiętać, że nasz plik źródłowy nie został naruszony. Nadal jest nienaruszona. Zmiany są wyświetlane na naszym ekranie.,
jeśli chcemy zapisać nasze edycje, możemy przekierować standardowe wyjście do pliku w następujący sposób:
- sed '1~2d' BSD > everyother.txt
teraz otwórz plik za pomocą cat
:
- cat everyother.txt
widzisz to samo wyjście, które wcześniej widziałeś na ekranie:
OutputAll rights reserved.Redistribution and use in source and binary forms, with or withoutare met: notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer in the3. Neither the name of the University nor the names of its contributors without specific prior written permission.. . .. . .
polecenie sed
domyślnie nie edytuje pliku źródłowego, ale można zmienić to zachowanie, przekazując opcję -i
, co oznacza „wykonaj zmiany na miejscu.”Spowoduje to zmianę pliku źródłowego.,
Ostrzeżenie: użycie przełącznika -i
spowoduje zastąpienie oryginalnego pliku, więc powinieneś używać go ostrożnie. Wykonaj operacje bez przełącznika -i
, a następnie ponownie uruchom polecenie z -i
po uzyskaniu tego, co chcesz, Utwórz kopię zapasową oryginalnego pliku lub przekieruj wyjście do pliku. Bardzo łatwo jest przypadkowo zmienić oryginalny plik za pomocą przełącznika -i
.
spróbujmy edytować plikeveryother.txt
, który właśnie stworzyłeś, na miejscu., Zmniejsz plik ponownie, usuwając co drugą linię
:
- sed -i '1~2d' everyother.txt
jeśli użyjesz cat
, aby wyświetlić plik z cat everyother.txt
, zobaczysz, że plik został edytowany.
opcja-i
może być niebezpieczna. Na szczęście sed
daje możliwość utworzenia pliku kopii zapasowej przed edycją.,
aby utworzyć plik kopii zapasowej przed edycją, Dodaj rozszerzenie kopii zapasowej bezpośrednio za opcją „-i”:
- sed -i.bak '1~2d' everyother.txt
tworzy to plik kopii zapasowej z rozszerzeniem .bak
, a następnie edytuje oryginalny plik na miejscu.
następnie dowiesz się, jak używaćsed
do wykonywania operacji wyszukiwania i zamiany.
zastępowanie tekstu
prawdopodobnie najbardziej znanym zastosowaniemsed
jest zastępowanie tekstu., sed
może wyszukiwać wzorce tekstowe za pomocą wyrażeń regularnych, a następnie zastępować znaleziony tekst czymś innym.
możesz dowiedzieć się więcej o wyrażeniach regularnych, korzystając z wyrażeń regularnych Grep, aby wyszukać wzorce tekstowe w Linuksie.
w swojej najbardziej podstawowej formie, możesz zmienić jedno słowo na drugie, używając następującej składni:
's/old_word/new_word/'
s
jest poleceniem zastępczym. Trzy ukośniki (/
) służą do oddzielenia różnych pól tekstowych., Możesz użyć innych znaków do oddzielania pól, jeśli byłoby to bardziej pomocne.
na przykład, jeśli próbujesz zmienić nazwę witryny, użycie innego ogranicznika byłoby pomocne, ponieważ adresy URL zawierają ukośniki.
wykonaj następujące polecenie, aby wydrukować adres URL z echo
I zmodyfikować go za pomocą sed
, używając podkreślnika (_
) jako ogranicznika:
- echo "http://www.example.com/index.html" | sed 's_com/index_org/home_'
zastępuje com/index
z org/home
., Wyjście pokazuje zmodyfikowany adres URL:
Output
Do not forget the final delimiter, or sed
will complain. If you ran this command:
- echo "http://www.example.com/index.html" | sed 's_com/index_org/home'
zobaczysz to wyjście:
Outputsed: -e expression #1, char 20: unterminated `s' command
utwórzmy nowy plik, aby przećwiczyć pewne podstawienia. Wykonaj następujące polecenie, aby utworzyć nowy plik tekstowy o nazwie song.txt
:
- echo "this is the song that never ends
- yes, it goes on and on, my friend
- some people started singing it
- not knowing what it was
- and they'll continue singing it forever
- just because..." > song.txt
teraz zastąp wyrażenieon
forward
. Użyj następującego polecenia:
- sed 's/on/forward/' song.txt
wyjście wygląda tak:
Outputthis is the sforwardg that never endsyes, it goes forward and on, my friendsome people started singing itnot knowing what it wasand they'll cforwardtinue singing it foreverjust because...
możesz zobaczyć kilka godnych uwagi rzeczy tutaj., Po pierwsze, sed
zastępuje wzorce, a nie słowa. on
w obrębiesong
zmienia się naforward
.
inną rzeczą do zauważenia jest to, że w linii 2, drugi on
nie został zmieniony na forward
.
dzieje się tak dlatego, że domyślnie polecenie s
działa przy pierwszym dopasowaniu w wierszu, a następnie przechodzi do następnego wiersza., Aby sed
zastąpić każdą instancję on
zamiast tylko pierwszej w każdej linii, musisz przekazać opcjonalną flagę do polecenia zastępczego.
podaj znacznikg
do polecenia zastępczego, umieszczając go po zestawie zastępczym:
- sed 's/on/forward/g' song.txt
zobaczysz to wyjście:
Outputthis is the sforwardg that never endsyes, it goes forward and forward, my friendsome people started singing itnot knowing what it wasand they'll cforwardtinue singing it foreverjust because...
teraz polecenie zastępcze zmienia się co instancja.,
Jeśli chcesz zmienić tylko drugą instancję „on”, którą sed znajdzie w każdej linii, użyj numeru 2
zamiast g
:
- sed 's/on/forward/2' song.txt
tym razem pozostałe linie są bez zmian, ponieważ nie mają sekundy występowanie:
Outputthis is the song that never endsyes, it goes on and forward, my friendsome people started singing itnot knowing what it wasand they'll continue singing it foreverjust because...
Jeśli chcesz zobaczyć tylko, które linie zostały podstawione, użyj opcji -n
, aby ponownie wyłączyć automatyczne drukowanie.,
Możesz następnie przekazać opcję p
do polecenia substitute, aby wydrukować wiersze, w których miało miejsce podstawianie.
- sed -n 's/on/forward/2p' song.txt
linia, która się zmieniła wyświetla się na ekranie:
Outputyes, it goes on and forward, my friend
jak widać, można połączyć flagi na końcu polecenia.
Jeśli chcesz, aby proces wyszukiwania ignorował wielkość liter, możesz przekazać mu flagę „i”.,
- sed 's/SINGING/saying/i' song.txt
oto wynik, który zobaczysz:
Outputthis is the song that never endsyes, it goes on and on, my friendsome people started saying itnot knowing what it wasand they'll continue saying it foreverjust because...
zastępowanie i odwoływanie się do dopasowanego tekstu
Jeśli chcesz znaleźć bardziej złożone wzorce z wyrażeniami regularnymi, masz wiele różnych metod odwoływania się do dopasowanego wzorca w tekście zastępczym.,
na przykład, aby dopasować Od początku linii do at
, użyj następującego polecenia:
- sed 's/^.*at/REPLACED/' song.txt
zobaczysz to wyjście:
Output REPLACED never endsyes, it goes on and on, my friendsome people started singing itREPLACED it wasand they'll continue singing it foreverjust because...
możesz zobaczyć, że wyrażenie wieloznaczne pasuje Od początku linii do ostatniej instancji at
.
ponieważ nie znasz dokładnej frazy, która będzie pasować do szukanego ciągu, możesz użyć znaku&
, aby reprezentować dopasowany tekst w ciągu zastępczym.,
umieśćmy nawiasy wokół dopasowanego tekstu:
- sed 's/^.*at/(&)/' song.txt
zobaczysz to wyjście:
Output (this is the song that) never endsyes, it goes on and on, my friendsome people started singing it(not knowing what) it wasand they'll continue singing it foreverjust because...
bardziej elastycznym sposobem odwoływania się do dopasowanego tekstu jest użycie nawiasów z odstępami do grupowania części dopasowanego tekstu.
każda grupa szukanego tekstu oznaczona nawiasami może być odwołana za pomocą unikalnego numeru referencyjnego. Na przykład, pierwsza grupa nawiasów może być odwołana do \1
, druga do \2
I tak dalej.,
w tym przykładzie przełączymy dwa pierwsze słowa każdej linii:
- sed 's/\(*\) \(*\)/\2 \1/' song.txt
zobaczysz to wyjście:
Output is this the song that never endsyes, goes it on and on, my friendpeople some started singing itknowing not what it wasthey and'll continue singing it foreverbecause just...
jak widzisz, wyniki nie są idealne. Na przykład, druga linia pomija pierwsze słowo, ponieważ ma znak niewymieniony w naszym zestawie znaków. Podobnie traktował they'll
jako dwa słowa w piątej linii.
poprawmy Wyrażenie regularne, aby było bardziej dokładne:
- sed 's/\(*\) \(*\)/\2 \1/' song.txt
zobaczysz to wyjście:
Output is this the song that never endsit yes, goes on and on, my friendpeople some started singing itknowing not what it wasthey'll and continue singing it foreverbecause... just
jest to znacznie lepsze niż ostatnio., To grupuje interpunkcję z powiązanym słowem.
zauważ, jak powtarzamy wyrażenie wewnątrz nawiasów (raz bez znaku *
, a następnie raz z nim). Dzieje się tak, ponieważ znak *
odpowiada zestawowi znaków, który jest przed nim zero lub więcej razy. Oznacza to, że mecz z wildcard będzie uważany za „mecz”, nawet jeśli wzór nie zostanie znaleziony.
aby zapewnić, żesed
znajdzie tekst przynajmniej raz, musisz dopasować go raz bez symbolu wildcard przed użyciem symbolu wildcard.,
podsumowanie
w tym tutorialu zapoznałeś się z poleceniemsed
. Wydrukowano określone wiersze z pliku, wyszukano tekst, usunięto wiersze, nadpisano oryginalny plik i użyto wyrażeń regularnych do zastąpienia tekstu. Powinieneś być już w stanie zobaczyć, jak można szybko przekształcić dokument tekstowy za pomocą odpowiednio skonstruowanych poleceń sed.
w następnym artykule z tej serii poznasz kilka bardziej zaawansowanych funkcji.