Sed ce înseamnă. Folosim editorul de text în flux sed pe Linux. Modificatori de substituție de comandă s

Introducere

Comanda sed este un Stream EDItor pentru editarea automată a textelor. „Editor de flux” - în sensul că poate edita fluxul de date primit în mod continuu, să zicem, ca parte a unui canal de program (conductă). Automat - aceasta înseamnă că, de îndată ce setați regulile de editare, restul se întâmplă fără participarea dvs. obositoare. Cu alte cuvinte, sed nu este interactiv.

Programul sed este mai complex decât comenzile pe care le-am acoperit deja în articolele anterioare din seria HuMan. Are un arsenal de comenzi proprii, așa că pentru a evita tautologia și confuzia, în acest articol comanda sed va fi denumită de acum înainte „program” sau „editor”, iar comenzile sed editor ca simple comenzi.

Programul sed este capabil să realizeze sarcini complexe și este nevoie de timp pentru a învăța cum să formulezi aceste sarcini.

Dar, alături de acțiuni complexe, comanda sed are caracteristici simple, dar foarte utile, care nu sunt mai greu de stăpânit decât alte comenzi Unix. Nu vă permiteți, din cauza complexității stăpânirii întregului program, să abandonați aspectele sale simple.

Vom începe de la simplu la complex, astfel încât să vă puteți da întotdeauna seama unde să vă opriți.

Comanda s - înlocuire (înlocuire)

Programul sed are multe comenzi native. Majoritatea utilizatorilor cunosc doar comanda s, iar acest lucru este suficient pentru a lucra cu editorul sed. Comanda s înlocuiește PATTERN cu REPLACE:

sed s /SAMPLE/REPLACE/

$ ecou ziua | sed s /zi/noapte/ (Intra) noapte

Nu devine mai ușor. Și iată un exemplu cu intrare din fișierul zar.txt:

Dimineața făcea exerciții. Fulgerul este o sarcină electrică. $ sed s/charge/descharge/ zar.txt Dimineața ar fi descărcat. Fulgerul este o descărcare electrică.

Nu am citat s/PATTERN/REPLACEMENT/ deoarece acest exemplu nu are nevoie de ghilimele, dar dacă ar fi prezente metacaractere, ghilimele ar fi necesare. Pentru a nu-ți sparge capul de fiecare dată, și pentru a nu greși din neatenție, pune mereu ghilimele, mai bine decât cele mai „puternice” singure, acesta este un obicei bun. Nu vei strica terciul cu ulei. Nici eu, în toate exemplele ulterioare, nu mă voi zgâri cu ghilimele.

După cum putem vedea, comanda de înlocuire s are patru componente:

S comanda în sine /.../.../ delimitator PATTERN model pentru a căuta și apoi înlocui expresia REPLACE care va înlocui PATTERN dacă este găsită una.

Bara oblică (/) este folosită în mod tradițional ca delimitator, deoarece strămoșul sed le folosește (la fel ca și vi). În unele cazuri, un astfel de separator este foarte incomod, de exemplu, atunci când trebuie să schimbați căile (calea) către directoare care conțin și o bară oblică (/usr/local/bin). În acest caz, trebuie să separați barele oblice înainte de cele inverse:

Sed "s/\/usr\/local\/bin/\/common\/bin/"

Aceasta se numește „palisadă” și arată foarte urât și, cel mai important, de neînțeles.

Unicitatea sed este că vă permite să utilizați orice delimitator, cum ar fi liniuța de subliniere:

$ ecou ziua | sed s_day_night_night

sau colon:

$ ecou ziua | sed s:day:night: night

Dacă căutați un delimitator care vă place, primiți mesajul „comandă incompletă `s””, atunci acest caracter nu este potrivit ca delimitator, sau pur și simplu ați uitat să puneți unul sau doi delimitatori.

În acest articol, sunt obligat să folosesc separatorul tradițional (/) pentru a nu deruta cititorul, dar dacă este necesar, voi folosi ca separator tilda (~).

Expresii regulate (RE)

(Expresii regulate, expresie regulată, RE)

Subiectul expresiilor obișnuite este atât de extins încât îi sunt dedicate cărți întregi (vezi link-urile de la sfârșitul articolului). Cu toate acestea, a vorbi serios despre sed fără a folosi expresii regulate este la fel de neproductiv ca și a vorbi despre trigonometrie cu bastoane de numărare. Prin urmare, este necesar să vorbim cel puțin despre acele expresii regulate care sunt adesea folosite cu programul sed.

Cu Sau orice altă scrisoare. Majoritatea literelor, numerelor și a altor caractere nespeciale sunt tratate ca expresii regulate care se reprezintă.

* Un asterisc care urmează oricărui caracter sau expresie regulată înseamnă orice număr (inclusiv zero) de repetări ale acestui caracter sau expresie regulată.

\+ Înseamnă una sau mai multe repetări ale unui caracter sau expresii regulate.

\? Înseamnă nici una sau o repetare.

\(i\)Înseamnă exact i repetări.

\(i,j\) Numărul de repetări este în intervalul de la i la j inclusiv.

\(i,\) Numărul de repetări este mai mare sau egal cu i.

\(,j\) Numărul de repetări este mai mic sau egal cu j.

\(RE\) Amintiți-vă expresia regulată sau o parte a acesteia în scopul utilizării ulterioare ca întreg. De exemplu, \(a-z\)* se va potrivi cu orice combinație de orice număr (inclusiv zero) de litere mici.

. Înseamnă orice caracter, inclusiv caracterul newline.

^ Înseamnă expresia nulă de la începutul șirului. Cu alte cuvinte, orice este precedat de acest caracter trebuie să apară la începutul rândului. De exemplu, ^#include va căuta linii care încep cu #include.

$ La fel ca mai sus, se aplică numai la sfârșitul liniei.

[LISTĂ]Înseamnă orice caracter din LISTĂ. De exemplu, va căuta orice vocală engleză.

[^LISTA]Înseamnă orice caracter, cu excepția celor din listă. De exemplu, [^aeiou] va căuta orice consoană. Notă: LISTA poate fi un interval, cum ar fi [a-z], care ar însemna orice literă mică. Dacă doriți să includeți un ] (paranteză pătrată) în LISTĂ, puneți-l pe primul loc în listă; dacă doriți să includeți - (cratima) în LISTĂ, atunci specificați-l în listă primul sau ultimul.

RE1\|RE2Înseamnă PB1 sau PB2.

RE1RE2Înseamnă unirea expresiilor regulate PB1 și PB2.

\n Indică un caracter de linie nouă.

\$; \*; \.; \[; \\; \^ Ele înseamnă, respectiv: $; *; .; [; \; ^

Atenţie: Alte convenții C backslash (\) nu sunt acceptate de sed.

\1 \2 \3 \4 \5 \6 \7 \8 \9 Înseamnă partea care se potrivește a expresiei regulate, stocată folosind \(și \).

Câteva exemple:

abcdefÎnseamnă abcdef

a*bÎnseamnă zero sau orice număr de litere a și o literă b. De exemplu, aaaaaab; ab; sau b.

a\?bÎnseamnă b sau ab

a\+b\+Înseamnă una sau mai multe litere a și una sau mai multe litere b. De exemplu: ab; aaaab; abbbbb; sau aaaaabbbbbbb.

.* Înseamnă toate caracterele de pe linie, pe toate liniile, inclusiv pe cele goale.

.\+ Înseamnă toate caracterele dintr-un șir, dar numai pe șirurile care conțin cel puțin un caracter. Liniile goale nu se potrivesc cu expresia regulată dată.

^principal.*(.*) Acesta va căuta linii care încep cu cuvântul principal, precum și care conțin paranteze de deschidere și de închidere și orice număr de caractere poate fi sau nu înainte și după paranteza de deschidere.

^# Va căuta linii care încep cu semnul # (de exemplu, comentarii).

\\$ Va căuta linii care se termină cu o bară oblică inversă (\).

Orice litere sau cifre

[^ ]\+ (Paranteza pătrată, pe lângă caracterul ^, conține, de asemenea, un spațiu și o tabulație) -- Înseamnă unul sau orice număr de caractere, cu excepția unui spațiu și a unei tabulare. De obicei înseamnă un cuvânt.

^.*A.*$Înseamnă litera majusculă A exact în mijlocul liniei.

A.\(9\)$ Indică litera A majusculă, exact a zecea de la sfârșitul rândului.

^.\(,15\)AÎnseamnă o literă mare A, exact a șaisprezecea de la începutul rândului.

Acum că am văzut câteva expresii regulate, să revenim la comanda lui sed.

Folosind & când PATTERN este necunoscut „Cum este necunoscut?” întrebi – „Nu știi ce vrei să înlocuiești?” Răspuns: Vreau să iau între paranteze orice numere găsite în text. Cum să o facă? Răspuns: utilizați simbolul &.

Caracterul & (ampersand), atunci când este plasat într-un REPLACEMENT, înseamnă orice MODEL găsit în text. De exemplu:

$ ecou 1234 | sed „s/*/(&)/” (1234)

Este necesar un asterisc (asterisc) după interval pentru a înlocui toate cifrele găsite în eșantion. Fără el, ar fi:

$ ecou 1234 | sed "s//(&)/" (1)234

Adică prima cifră găsită a fost luată ca probă.

Iată un exemplu cu o încărcare complet semnificativă: să creăm un fișier formula.txt:

A+432-10=n

și aplicați-i comanda:

$ sed „s/*-*/(&)/” formula.txt a+(432-10)=n

Formula matematică a căpătat un sens clar.

Un alt caracter ampersand poate fi folosit pentru a dubla MODELUL:

$ ecou 123 | sed "s/*/& &/" 123 123

Există o subtilitate aici. Dacă complicăm puțin exemplul:

$ echo „123 abc” | sed "s/*/& &/" 123 123 abc

după cum era de așteptat, doar cifrele sunt dublate, deoarece nu există litere în PATTERN. Dar dacă schimbăm părți din text:

$ echo „abc 123” | sed "s/*/& &/" abc 123

atunci nici o dublare a numerelor nu va funcționa. Aceasta este o caracteristică a expresiei regulate * - se potrivește doar cu primul caracter al șirului. Dacă vrem să dublăm cifrele oriunde se află, trebuie să modificăm expresia regulată din REPLACE:

$ echo "abc defg 123" | sed "s/*/& &/" abc defg 123 123

atunci cifrele vor fi dublate, indiferent de numărul de „cuvinte” precedente.

Utilizarea caracterelor de evacuare \(, \) și \1 pentru a gestiona partea PATTERN Caracterele de evadare \( și \) (paranteze escape) sunt folosite pentru a reține partea expresiei regulate.

Simbolul \1 înseamnă prima parte memorată, \2 - a doua și așa mai departe, până la nouă părți memorate (programul nu acceptă mai multe). Să luăm un exemplu:

$ echo abcd123 | sed "s/\(*\).*/\1/" abcd

Aici \(*\) înseamnă că programul ar trebui să rețină toate caracterele alfabetice în orice cantitate; .* înseamnă orice număr de caractere după prima parte memorată; iar \1 înseamnă că vrem să vedem doar prima parte memorată. Așa este: în ieșirea programului, vedem doar litere și nici un număr.

Pentru a schimba cuvintele, trebuie să vă amintiți două sub-PROBE, apoi să le schimbați:

$ echo stupid pinguin |sed "s/\([a-z]*\) \([a-z]*\)/\2 \1/" prost pinguin

Aici \2 înseamnă al doilea sub-model și \1 înseamnă primul. Observați distanța dintre prima expresie \([a-z]*\) și a doua expresie \([a-z]*\). Este necesar ca două cuvinte să fie găsite.

Caracterul \1 nu trebuie să fie doar în REPLACEMENT, el poate fi prezent și în PATTERN, de exemplu, când dorim să eliminăm cuvintele duplicate:

$ ecou pinguin pinguin | sed "s/\([a-z]*\) \1/\1/" pinguin

Modificatori de substituție de comandă s

Modificatorii de înlocuire sunt plasați după ultimul delimitator. Acești modificatori determină ce va face programul dacă există mai multe potriviri PATTERN într-un șir și cum să-l înlocuiască.

modificator /g

Înlocuire globală

Programul sed, ca majoritatea utilitarelor Unix, citește câte o linie atunci când lucrează cu fișiere. Dacă ordonăm înlocuirea unui cuvânt, programul va înlocui doar primul cuvânt care se potrivește pe linia dată. Dacă vrem să schimbăm fiecare cuvânt care se potrivește cu modelul, atunci trebuie introdus modificatorul /g.

Fără modificatorul /g:

$ echo această pisică a fost cea mai comună pisică | sed "s / cat / kitten /" acest pisoi era cea mai obisnuita pisica

Editorul a înlocuit doar primul cuvânt potrivit.

Și acum cu modificatorul de înlocuire globală:

$ echo această pisică a fost cea mai comună pisică | sed "s/cat/kitten/g" acest pisoi era cel mai comun pisoi

Toate potrivirile din șirul dat au fost înlocuite.

Și dacă trebuie să schimbați toate cuvintele, să spuneți, puneți-le între paranteze? Apoi expresiile regulate vin din nou în ajutor. Pentru a selecta toate caracterele alfabetice, atât majuscule, cât și minuscule, puteți folosi construcția [A-Zaa-z], dar cuvinte precum „ceva” sau „cu” plimbări nu vor cădea în ea. Mult mai convenabilă este construcția [ ^ ]* care se potrivește cu toate caracterele, cu excepția spațiilor albe, deci:

$ echo stupid pinguin se ascunde timid | sed "s/[^ ]*/(&)/g" (prost) (pinguin) (timid) (ascunde)

Cum să alegi potrivirea dorită dintre mai multe

Dacă nu sunt aplicați modificatori, sed va înlocui doar primul cuvânt care se potrivește cu PATTERN. Dacă aplicați modificatorul /g, programul va înlocui fiecare cuvânt potrivit. Și cum poți selecta unul dintre potriviri dacă există mai multe pe o linie? - Folosind simbolurile \ (și \) deja familiare nouă, amintiți-vă de sub-PROBE și selectați-l pe cel de care aveți nevoie folosind simbolurile \ 1 - \ 9.

$ echo stupid pinguin | sed "s/\([a-z]*\) \([a-z]*\)/\2 /" pinguin

În acest exemplu, am memorat ambele cuvinte, iar punând al doilea (pinguin) pe primul loc, l-am eliminat pe primul (prost) punând un spațiu în secțiunea ÎNLOCUIRE. Dacă punem orice cuvânt în loc de spațiu, atunci acesta îl va înlocui pe primul (prost):

$ echo stupid pinguin | sed "s/\([a-z]*\) \([a-z]*\)/\2 inteligent /" pinguin inteligent

Modificator numeric

Acesta este un număr de una/două/trei cifre care vine după ultimul delimitator și indică ce potrivire urmează să fie înlocuită.

$ ecou pinguin foarte prost | sed "s/[a-z]*/good/2" pinguin foarte bun

În acest exemplu, fiecare cuvânt este o potrivire și i-am spus editorului ce cuvânt dorim să înlocuim punând un modificator 2 după secțiunea ÎNLOCUIRE.

Puteți combina modificatorul digital cu modificatorul /g. Dacă trebuie să lăsați primul cuvânt neschimbat și să îl înlocuiți pe al doilea și pe cele ulterioare cu cuvântul „(șters)”, atunci comanda va fi următoarea:

$ ecou pinguin foarte prost | sed "s/[a-z]*/(șters)/2g" foarte (șters) (șters)

Dacă doriți cu adevărat să eliminați toate potrivirile ulterioare, cu excepția primei, atunci puneți un spațiu în secțiunea ÎNLOCUIRE:

$ ecou pinguin foarte prost | sed "s/[a-z]*/ /2g" foarte

Sau nu faci nimic:

$ ecou pinguin foarte prost | sed "s/[^ ]*//2g" este foarte

Modificatorul numeric poate fi orice număr întreg de la 1 la 512. De exemplu, dacă trebuie să puneți două puncte după al 80-lea caracter al fiecărei linii, atunci comanda vă va ajuta:

$ sed numele fișierului „s/./&:/80”.

Modificator /p - ieșire la ieșire standard (printare - imprimare)

Programul sed, implicit, scoate rezultatul la ieșirea standard (de exemplu, ecranul monitorului). Acest modificator este folosit numai cu opțiunea sed -n, care doar blochează ieșirea rezultatului pe ecran.

modificator /w

Vă permite să scrieți rezultatele procesării textului în fișierul specificat:

$ sed "s /PATTERN/REPLACE /w nume de fișier

Modificator /e (extensie GNU)

Vă permite să specificați o comandă shell (nu programul sed) ca ÎNLOCUIT. Dacă se găsește o potrivire cu PATTERN, aceasta va fi înlocuită cu ieșirea comenzii specificate în secțiunea REPLACE. Exemplu:

$ ecou noapte | sed „s/night/echo day/e” zi

Modificatori /I și /i (extensia GNU)

Faceți ca procesul de înlocuire să nu țină seama de majuscule și minuscule.

$echo Night | sed "s/night/day/i" zi

Combinații modificatoare

Modificatorii pot fi combinați atunci când are sens. În acest caz, modificatorul w ar trebui plasat ultimul.

Convenții (extensia GNU) Există doar cinci dintre ele:

\L convertește caracterele REPLACEMENT în litere mici \l convertește următorul caracter REPLACE în minuscule \U convertește caracterele REPLACEMENT în majuscule \u convertește următorul caracter REPLACE în majuscule \E anulează o traducere începută cu \L sau \U Din motive evidente, aceste convenții sunt folosite singure. De exemplu:

$ echo stupid pinguin | sed "s/prost/\u&/" Pinguin prost

$ echo mic catelus | sed „s/[a-z]*/\u&/2” cățeluș

Am acoperit aproape fiecare aspect al comenzii lui sed. Acum este rândul să luăm în considerare opțiunile acestui program.

opțiunile programului sed

Programul are surprinzător de puține opțiuni. (Ceea ce compensează oarecum excesul de comenzi, modificatori și alte funcții). Pe lângă opțiunile binecunoscute --help (-h) și --version (-V), pe care nu le vom lua în considerare, există doar trei dintre ele:

Opțiunea -e--expression=set de comenzi

O modalitate de a rula mai multe comenzi este să utilizați opțiunea -e. De exemplu:

Sed -e „s/a/A/” -e „s/b/B/” nume de fișier

Toate exemplele anterioare din acest articol nu necesitau opțiunea -e doar pentru că conțineau o singură comandă. Am putea pune optiunea -e in exemple, nu ar schimba nimic.

Opțiunea -f Dacă trebuie să executați un număr mare de comenzi, este mai convenabil să le scrieți într-un fișier și să utilizați opțiunea -f:

sed -f nume de fișier sedscript

Sedscript aici este numele fișierului care conține comenzile. Acest fișier se numește scriptul programului sed (denumit în continuare simplu script). Fiecare comandă de script ar trebui să ocupe o linie separată. De exemplu:

# comentariu - Acest script va schimba toate vocalele minuscule în majuscule s/a/A/g s/e/E/g s/i/I/g s/o/O/g s/u/U/g

Puteți denumi scriptul cum doriți, este important să nu confundați fișierul script cu fișierul în curs de procesare.

Opțiunea -n Programul sed -n nu scoate nimic la ieșirea standard. Pentru a obține rezultatul, aveți nevoie de o instrucțiune specială. Am văzut deja modificatorul /p, care poate fi folosit pentru a da o astfel de indicație. Să ne amintim fișierul zar.txt:

$ sed "s/1-9/&/p" zar.txt Dimineata si-a facut exercitiile. Fulgerul este o sarcină electrică.

Deoarece nu s-au găsit potriviri cu PATTERN (nu există numere în fișier), comanda s cu modificatorul /p și semnul & ca ÎNLOCUIT (amintiți-vă că ampersand înseamnă PATTERN în sine) funcționează ca comanda cat.

Dacă PATTERN este găsit în fișier, atunci liniile care conțin PATTERN vor fi dublate:

$ sed "s/exercises/&/p" zar.txt Dimineata facea exercitii. Dimineața făcea exerciții. Fulgerul este o sarcină electrică.

Acum să adăugăm opțiunea -n:

$ sed -n "s/charge/&/p" zar.txt Dimineata si-a facut exercitiile.

Acum programul nostru funcționează ca o comandă grep - returnează doar liniile care conțin PATTERN.

Selectarea elementelor dorite ale textului editabil

Cu o singură comandă, s, am văzut puterea uimitoare a editorului sed. Dar tot ce face este să caute și să înlocuiască. Mai mult, în procesul de lucru, sed editează fiecare rând pe rând, fără să acorde atenție celorlalți. Ar fi convenabil să se limiteze gama de linii care trebuie schimbate, de exemplu:

  • Selectați rândurile după număr
  • Selectați rânduri dintr-un interval de numere
  • Selectați numai rânduri care conțin o expresie
  • Selectați numai rânduri între unele expresii
  • Selectați numai linii de la începutul fișierului până la o expresie
  • Selectați numai linii de la o expresie până la sfârșitul fișierului

Programul sed face toate acestea și multe altele. Orice comandă a editorului sed poate fi aplicată în funcție de adresă, unui interval de adrese sau cu restricțiile de mai sus în intervalul de linii. Adresa sau constrângerea trebuie să precedă imediat comanda:

Sed "adresă/comandă limită"

Selectați rândurile după numere

Acesta este cel mai simplu caz. Trebuie doar să specificați numărul liniei dorite înainte de comandă:

$ sed "4 s/[a-z]*//i" gumilev.txt Ce fericire ciudată În amurgul devreme al dimineții, În topirea zăpezii de primăvară, tuturor celor ce piere și sunt înțelepți.

$ sed "3 s/B/(B)/" gumilev.txt Ce fericire ciudată În amurgul devreme al dimineții, (În) topirea zăpezii de primăvară, În tot ce piere și este înțelept.

Selectarea rândurilor dintr-un interval de numere

Intervalul este indicat, deloc surprinzător, separat prin virgule:

$ sed "2.3 s/B/(B)/" gumilev.txt Ce fericire ciudată (În) amurgul devreme al dimineții, (În) topirea zăpezii de primăvară, În tot ce piere și este înțelept.

Dacă trebuie să specificați un interval până la ultima linie a fișierului și nu știți câte linii conține, atunci utilizați semnul $:

$ sed "2,$ s/in/(in)/i" gumilev.txt Ce fericire ciudată (în) amurgul devreme al dimineții, (în) topirea zăpezii de primăvară, (în) tot ce piere și este înţelept.

Selectarea rândurilor care conțin o expresie

Expresia de căutare este inclusă în bare oblice (/) și este plasată înaintea comenzii:

$ sed "/dimineața/ s/in/(in)/i" gumilev.txt Ce fericire ciudată (în) amurgul devreme al dimineții, În topirea zăpezii de primăvară, În tot ce piere și este înțelept.

Selectarea rândurilor dintr-un interval între două expresii

Ca și în cazul numerelor de rând, intervalul este specificat separat prin virgule:

$ sed "/dimineața/,/înțelept/ s/in/(în)/i" gumilev.txt Ce fericire ciudată (în) amurgul devreme al dimineții, (în) topirea zăpezii de primăvară, (în) toate care piere și este înțelept .

Selectarea liniilor de la începutul unui fișier până la o expresie

$ sed "1,/snow/ s/in/(in)/i" gumilev.txt Ce fericire ciudată (în) amurgul devreme al dimineții, (în) topirea zăpezii de primăvară, În tot ce piere și este înţelept.

Selectarea liniilor de la o expresie până la sfârșitul fișierului

$ sed "/zăpadă/,$ s/in/(in)/i" gumilev.txt Ce fericire ciudată În amurgul devreme al dimineții, (în) topirea zăpezii de primăvară, (în) tot ce piere și este înţelept.

Alte comenzi sed

d comandă (ștergere)

Elimină liniile specificate din ieșirea standard:

$ sed "2 d" gumilev.txt Ce fericire ciudată În topirea zăpezii de primăvară, În tot ceea ce piere și este înțelept.

Și mai des scriu mai ușor (fără spațiu):

Sed "2d" gumilev.txt

Tot ceea ce s-a spus în secțiunea anterioară despre adresarea liniei se aplică comenzii d (așa cum se întâmplă cu aproape toate comenzile editorului sed).

Folosind comanda d, este convenabil să aruncați un „antet” inutil al unui mesaj de e-mail:

$ sed „1,/^$/ d” nume de fișier

(Ștergeți liniile de la prima la prima linie goală).

Scăpați de comentariile din fișierul de configurare:

$ sed "/^#/d" /boot/grub/menu.lst

Și nu știi niciodată unde trebuie să elimini liniile suplimentare!

comanda p (printare)

Cuvântul englezesc „print” este tradus ca „print”, care în rusă este asociat cu o imprimantă sau cel puțin cu o tastatură. De fapt, în contextul englez, acest cuvânt înseamnă adesea pur și simplu ieșire pe ecranul monitorului. Deci comanda p nu tipărește nimic, doar tipărește liniile specificate pe ecran.

Folosită de la sine, comanda p dublează liniile din ieșire (deoarece programul sed tipărește o linie pe ecran în mod implicit, iar comanda p tipărește aceeași linie a doua oară).

$ echo am o pisica | sed "p" am o pisică am o pisică

Această proprietate este folosită, de exemplu, pentru a dubla liniile goale pentru a îmbunătăți aspectul textului:

$ sed "/^$/ p nume de fișier

Dar comanda p își dezvăluie adevărata față în combinație cu opțiunea -n, care, după cum vă amintiți, interzice ieșirea liniilor pe ecran. Combinând opțiunea -n cu comanda p, puteți obține numai liniile de care aveți nevoie în rezultat.

De exemplu, uitați-vă la rândurile unu până la zece:

$ sed -n Nume fișier „1,10 p”.

Sau doar comentarii:

$ sed -n "/^#/ p" /boot/grub/menu.lst # Fișierul de configurare GRUB "/boot/grub/menu.lst". # generat de „grubconfig”. Duminica 23 mar 2008 21:45:41 # # Porniți secțiunea globală GRUB # Încheiați secțiunea globală GRUB # Începe configurația partiției de pornire Linux # Se termină configurația partiției de pornire Linux # Începe configurația partiției de pornire Linux # Se termină configurația partiției de pornire Linux

Care este foarte asemănător cu grep, pe care l-am întâlnit deja când am vorbit despre opțiunea -n cu modificatorul /p. Dar, spre deosebire de comanda grep, editorul sed face posibilă nu numai găsirea acestor linii, ci și schimbarea lor, înlocuind, de exemplu, peste tot Linux cu Unix:

$ sed -n "/^#/p" /boot/grub/menu.lst | sed "s/Linux/Unix/" # Fișierul de configurare GRUB "/boot/grub/menu.lst". # generat de „grubconfig”. Duminica 23 Mar 2008 21:45:41 # # Porniți secțiunea globală GRUB # Încheiați secțiunea globală GRUB # Începe configurația partiției de pornire Unix # Se termină configurația partiției de pornire Unix # Începe configurația partiției de pornire Unix # Se termină configurația partiției de boot Unix

Echipă!

Uneori trebuie să editați toate liniile, cu excepția celor care se potrivesc cu un PATTERN sau cu o selecție. Caracterul semn de exclamare (!) inversează selecția. De exemplu, să ștergem toate liniile, cu excepția celui de-al doilea din catrenul lui Gumilyov:

$ sed "2 !d" gumilev.txt În amurgul devreme al dimineții,

Sau selectați toate rândurile cu excepția comentariilor din fișierul /boot/grub/menu.lst:

$ sed -n "/^#/ !p" /boot/grub/menu.lst implicit 1 timeout 20 gfxmenu (hd0,3)/boot/message title SuSe on (/dev/hda3) root (hd0,2) kernel /boot/vmlinuz root=/dev/hda3 ro vga=773 acpi=off title Linux on (/dev/hda4) root (hd0,3) kernel /boot/vmlinuz root=/dev/hda4 ro vga=0x317

comanda q (iesire)

Comanda q termină programul sed după linia specificată. Acest lucru este util dacă doriți să opriți editarea după ce ajungeți la un anumit punct al textului:

$ sed „11 q” nume de fișier

Această comandă va termina de lucru pentru a ajunge la a 11-a linie.

Comanda q este una dintre puținele comenzi sed care nu acceptă intervale de linii. Echipa nu poate înceta să lucreze de 10 ori la rând dacă introducem:

Sed "1.10 q" Absurd!

w (scriere) comandă

La fel ca modificatorul w al comenzii s, această comandă vă permite să scrieți rezultatul unui program într-un fișier:

$ sed -n "3,$w gum.txt" gumilev.txt

Vom obține fișierul gumilev.txt care conține ultimele două rânduri ale catrenului lui Gumilev din fișierul gumilev.txt. Mai mult, dacă un astfel de fișier există deja, acesta va fi suprascris. Dacă nu introduceți opțiunea -n, atunci programul, pe lângă crearea fișierului gum.txt, va afișa pe ecran și întregul conținut al fișierului gumilev.txt.

Pentru a lucra pe linia de comandă, este mai convenabil să folosiți redirecționarea obișnuită a ieșirii (> sau >>), dar în scripturile sed, comanda w își va găsi probabil utilizarea.

comanda r (citește)

Această comandă nu numai că va citi fișierul specificat, dar va insera și conținutul acestuia în locația dorită din fișierul editat. Pentru a selecta „locul necesar” adresarea ne este deja familiară (prin numere de rând, după expresii etc.). Exemplu:

$ echo Din poemul lui Gumilev: | sed "rgumilev.txt"

Dintr-o poezie de Gumiliov:

Ce fericire ciudată În amurgul devreme al dimineții, În topirea zăpezii de primăvară, În tot ce piere și este înțelept.

Comanda =

Oferă numărul liniei specificate:

$ sed "/snow/=" gumilev.txt Ce fericire ciudată În amurgul devreme al dimineții, 3 În topirea zăpezii de primăvară, În tot ce piere și este înțelept.

$ sed -n "/snow/=" gumilev.txt 3

Comanda acceptă o singură adresă, nu acceptă intervale.

Echipa y

Această comandă înlocuiește caracterele din secțiunea PATTERN cu caracterele din secțiunea REPLACE, funcționând ca un program tr.

$ echo Car - moștenire a trecutului | sed "y/Auto/Paro/" Paromobile - moștenire a trecutului

Echipă y funcționează numai dacă numărul de caractere din PATTERN este egal cu numărul de caractere din REPLACE.

scripturi de program sed

Pentru a utiliza sed ca editor de text complet, trebuie să învățați cum să scrieți scripturi sed. Programul sed are propriul său limbaj de programare simplu, care vă permite să scrieți scripturi care pot face minuni.

Acest articol nu poate conține descrieri ale scripturilor sed și nici autorul său nu își pune sarcina de a stăpâni limbajul de programare sed. În acest articol, m-am concentrat pe utilizarea editorului sed pe linia de comandă, cu accent pe utilizarea lui ca filtru în conducte. Din acest motiv, am omis numeroase comenzi sed care sunt folosite doar în scripturile sale.

Există mulți fani ai editorului sed și multe articole pe tema scripturilor, inclusiv în Runet. Așadar, pentru cei interesați de acest program minunat, nu va fi dificil să-și completeze cunoștințele.

Programul sed și caractere chirilice

După cum puteți vedea din exemplele din acest articol, programul sed pe un sistem rusificat corespunzător este fluent în limbajul „mare și puternic”.

Rezumatul programului sed

Programul sed este un editor multifuncțional de flux de date, indispensabil pentru:

  • Editarea matricelor de text mari
  • Editarea fișierelor de orice dimensiune atunci când secvența pașilor de editare este prea complexă
  • Editarea datelor pe măsură ce acestea devin disponibile, inclusiv în timp real - adică în cazurile în care este dificil sau imposibil să utilizați editori de text interactiv.

Va dura săptămâni sau chiar luni de muncă pentru a stăpâni pe deplin programul sed, deoarece acest lucru necesită:

  • Învață expresii regulate
  • Aflați cum să scrieți scripturi sed învățând limbajul de programare simplu folosit în aceste scripturi

Pe de altă parte, câteva dintre cele mai comune comenzi sed sunt la fel de ușor de stăpânit ca orice comandă Unix; Sper că acest articol vă va ajuta în acest sens.

Postfaţă

Până acum, în articolele ciclului HuMan, am încercat să dezvălui măcar pe scurt fiecare opțiune, fiecare parametru al comenzii descrise, astfel încât articolul să poată înlocui mana. În viitor, voi continua să adere la acest principiu.

Acest articol este o excepție, deoarece nu descrie toate caracteristicile programului. Pentru a le descrie pe deplin ar fi nevoie nu de un articol, ci de o carte. Cu toate acestea, articolul vă permite să vă faceți o idee despre editorul sed și să începeți cu acest program uimitor folosind cele mai comune comenzi ale sale.

Ultima dată am vorbit despre funcțiile din scripturile bash, în special despre cum să le apelăm din linia de comandă. Subiectul nostru de astăzi este un instrument foarte util pentru procesarea datelor șir - un utilitar Linux numit sed. Este adesea folosit pentru a lucra cu texte care arată ca fișiere jurnal, fișiere de configurare și alte fișiere.



Dacă manipulați datele într-un fel în scripturi bash, va trebui să vă familiarizați cu instrumentele sed și gawk. Aici ne vom concentra pe sed și lucrul cu texte, deoarece acesta este un pas foarte important în călătoria noastră prin vastele întinderi ale dezvoltării scriptului bash.

Acum vom analiza elementele de bază ale lucrului cu sed, precum și vom analiza mai mult de trei duzini de exemple de utilizare a acestui instrument.

bazele sed

Utilitarul sed se numește editor de text în flux. Editoarele de text interactive precum nano lucrează cu texte folosind tastatura, editând fișiere, adăugând, ștergând sau schimbând texte. Sed vă permite să editați fluxuri de date pe baza unui set de reguli definite de dezvoltator. Iată cum arată schema de apelare a acestei comenzi:

fișier de opțiuni $ sed
În mod implicit, sed aplică regulile specificate atunci când este invocat, exprimate ca un set de comenzi, la STDIN . Acest lucru permite transmiterea datelor direct către sed.

De exemplu, așa:

$ echo „Acesta este un test” | sed "s/test/alt test/"
Iată ce se întâmplă când rulați această comandă.


Un exemplu simplu de apel sed

În acest caz, sed înlocuiește cuvântul „test” din șirul trecut pentru procesare cu cuvintele „alt test”. Barele oblice drepte sunt folosite pentru a formata regula pentru procesarea textului cuprins între ghilimele. În cazul nostru, a fost folosită o comandă precum s/pattern1/pattern2/. Litera „s” este o abreviere a cuvântului „înlocuitor”, adică avem o echipă de înlocuire. Sed, executând această comandă, va privi textul transferat și va înlocui fragmentele găsite în el (vom vorbi despre care, despre care vom vorbi mai jos), corespunzătoare modelului1 , cu model2 .

Cele de mai sus este un exemplu primitiv de utilizare a sed, doar pentru a începe. De fapt, sed poate fi folosit în scenarii mult mai complexe de procesare a textului, cum ar fi lucrul cu fișiere.

Mai jos este un fișier care conține o bucată de text și rezultatele procesării acestuia cu această comandă:

$ sed "s/test/alt test" ./fișierul meu


Fișierul text și rezultatele procesării acestuia

Aici se aplică aceeași abordare pe care am folosit-o mai sus, dar acum sed procesează textul stocat în fișier. Cu toate acestea, dacă fișierul este suficient de mare, este posibil să observați că sed procesează datele în bucăți și afișează ceea ce este procesat pe ecran, fără a aștepta ca întregul fișier să fie procesat.

Sed nu modifică datele din fișierul în curs de procesare. Editorul citește fișierul, procesează ceea ce citește și trimite rezultatul la STDOUT . Pentru a vă asigura că fișierul sursă nu s-a schimbat, este suficient, după ce a fost trecut la sed, să îl deschideți. Dacă este necesar, rezultatul sed poate fi redirecționat către un fișier, eventual suprascriind fișierul vechi. Dacă sunteți familiarizat cu unul dintre articolele anterioare din această serie, care se ocupă cu redirecționarea fluxurilor de intrare și de ieșire, ar trebui să puteți face acest lucru.

Executarea seturilor de comenzi la apelarea sed

Pentru a efectua mai multe operații asupra datelor, utilizați opțiunea -e când apelați sed. De exemplu, iată cum să organizați înlocuirea a două bucăți de text:

$ sed -e "s/This/That/; s/test/alt test/" ./myfile


Folosind comutatorul -e când apelați sed

Ambele comenzi sunt aplicate fiecărei linii de text din fișier. Ele trebuie separate prin punct și virgulă și nu trebuie să existe un spațiu între sfârșitul comenzii și punct și virgulă.
Pentru a introduce mai multe modele de procesare a textului atunci când apelați sed, puteți, după ce ați introdus primul ghilimeleu simplu, să apăsați Enter și apoi să introduceți fiecare regulă pe o nouă linie, fără a uita ghilimele de închidere:

$ sed -e "> s/This/That/ > s/test/alt test/" ./myfile
Iată ce se întâmplă după ce comanda, prezentată în această formă, este executată.


Un alt mod de a lucra cu sed

Citirea comenzilor dintr-un fișier

Dacă există multe comenzi sed cu care să procesați textul, de obicei cel mai bine este să le scrieți mai întâi într-un fișier. Pentru a spune lui sed un fișier care conține comenzi, utilizați comutatorul -f:

Iată conținutul fișierului mycommands:

S/Acest/Aceasta/ s/test/alt test/
Să numim sed, trecând editorului un fișier cu comenzi și un fișier de procesat:

$ sed -f comenzile mele fișierul meu
Rezultatul apelării unei astfel de comenzi este similar cu cel obținut în exemplele anterioare.


Utilizarea unui fișier cu comenzi la apelarea sed

Înlocuiți steaguri de comandă

Aruncă o privire atentă la următorul exemplu.

$ sed "s/test/alt test/" fişierul meu
Iată ce este în fișier și ce va fi produs atunci când sed îl procesează.


Fișierul sursă și rezultatele prelucrării acestuia

Comanda de înlocuire procesează în mod normal un fișier format din mai multe linii, dar numai primele apariții ale fragmentului de text căutat de pe fiecare linie sunt înlocuite. Pentru a înlocui toate aparițiile unui model, trebuie utilizat steag-ul corespunzător.

Sintaxa pentru scrierea unei comenzi de înlocuire atunci când se utilizează steaguri arată astfel:

S/model/înlocuire/steaguri
Executarea acestei comenzi poate fi modificată în mai multe moduri.

  • La trecerea numărului, se ia în considerare numărul de serie al apariției șablonului din șir, această apariție va fi înlocuită.
  • Indicatorul g indică faptul că toate aparițiile modelului din șir ar trebui procesate.
  • Indicatorul p indică faptul că ar trebui să fie scos conținutul șirului original.
  • Indicatorul de fișier w spune comenzii să scrie rezultatele procesării textului într-un fișier.
Luați în considerare utilizarea primei variante a comenzii de înlocuire, indicând poziția apariției înlocuite a fragmentului dorit:

$ sed "s/test/un alt test/2" fișierul meu

Apelarea comenzii de înlocuire care specifică poziția fragmentului de înlocuit

Aici am specificat ca indicator de înlocuire numărul 2. Acest lucru a condus la faptul că numai a doua apariție a modelului dorit din fiecare linie a fost înlocuită. Acum să încercăm steagul de înlocuire global - g:

$ sed "s/test/alt test/g" fișierul meu
După cum puteți vedea din rezultat, această comandă a înlocuit toate aparițiile modelului din text.


Înlocuire globală

Indicatorul de comandă de substituție p permite ieșirea liniilor care se potrivesc, în timp ce opțiunea -n specificată la invocarea sed suprimă ieșirea normală:

$ sed -n "s/test/alt test/p" fișierul meu
Ca urmare, atunci când sed este rulat în această configurație, doar liniile (în cazul nostru, o linie) în care se găsește fragmentul de text dat sunt afișate pe ecran.


Utilizarea semnalizatorului de comandă de înlocuire p

Să folosim steag-ul w, care vă permite să salvați rezultatele procesării textului într-un fișier:

$ sed "s/test/alt test/w output" fișierul meu


Salvarea rezultatelor procesării textului într-un fișier

Se vede clar că în timpul funcționării comenzii, datele sunt scoase la STDOUT , în timp ce liniile procesate sunt scrise în fișierul al cărui nume este specificat după w .

Caractere delimitare

Imaginați-vă că înlocuiți /bin/bash cu /bin/csh în /etc/passwd . Sarcina nu este atât de dificilă:

$ sed "s/\/bin\/bash/\/bin\/csh/" /etc/passwd
Totuși, nu arată foarte bine. Chestia este că, deoarece barele oblice sunt folosite ca caractere separatoare, aceleași caractere din liniile transmise către sed trebuie să fie eliminate. Drept urmare, lizibilitatea comenzii are de suferit.

Din fericire, sed ne permite să setăm singuri caracterele delimitatoare pe care să le folosim în comanda de înlocuire. Delimitatorul este primul caracter care apare după s:

$ sed "s!/bin/bash!/bin/csh!" /etc/passwd
În acest caz, un semn de exclamare este folosit ca delimitator, făcând codul mai ușor de citit și mult mai curat decât înainte.

Selectarea fragmentelor de text pentru procesare

Până acum, am apelat la sed pentru a procesa tot ce a transmis editorului. În unele cazuri, doar o parte a textului trebuie procesată cu sed - o anumită linie sau un grup de linii. Există două abordări pentru atingerea acestui obiectiv:
  • Stabiliți o limită pentru numărul de linii procesate.
  • Specificați filtrul care se potrivește cu rândurile pe care doriți să le procesați.
Să luăm în considerare prima abordare. Există două opțiuni posibile aici. Prima, discutată mai jos, prevede specificarea numărului unei linii de procesat:

$ sed "2s/test/alt test/" fişierul meu


Se procesează o singură linie, numărul dat la apelul sed

A doua opțiune este o serie de șiruri de caractere:

$ sed "2,3s/test/alt test/" fişierul meu


Gestionarea intervalului de rânduri

În plus, puteți apela comanda înlocuire, astfel încât fișierul să fie procesat de la o anumită linie până la sfârșit:

$ sed "2,$s/test/alt test/" fişierul meu


Procesarea unui fișier de la a doua linie până la sfârșit

Pentru a procesa numai linii care se potrivesc cu filtrul specificat folosind comanda înlocuire, comanda trebuie apelată astfel:

$ sed "/likegeeks/s/bash/csh/" /etc/passwd
Prin analogie cu cele discutate mai sus, șablonul este trecut înaintea numelui comenzii s .


Procesarea rândurilor care se potrivesc cu un filtru

Aici am folosit un filtru foarte simplu. Pentru a dezvălui pe deplin posibilitățile acestei abordări, puteți folosi expresii regulate. Despre ele vom vorbi într-unul dintre următoarele articole din această serie.

Eliminarea rândurilor

Utilitarul sed este bun pentru mai mult decât pentru a înlocui secvențe de caractere din șiruri de caractere cu altele. Cu ajutorul acestuia, și anume, folosind comanda d, puteți șterge linii din fluxul de text.

Apelul de comandă arată astfel:

$ sed "3d" myfile
Dorim ca a treia linie să fie eliminată din text. Rețineți că acesta nu este un fișier. Fișierul va rămâne neschimbat, ștergerea va afecta doar rezultatul generat de sed.


Eliminarea a treia linie

Dacă nu specificați numărul liniei de șters atunci când apelați comanda d, toate liniile din flux vor fi șterse.

Iată cum să aplicați comanda d la o serie de linii:

$ sed "2,3d" myfile


Ștergerea unui interval de rânduri

Și iată cum să ștergeți linii, începând de la cea dată - și până la sfârșitul fișierului:

$ sed "3,$d" fișierul meu


Ștergeți liniile până la sfârșitul fișierului

Rândurile pot fi, de asemenea, șterse conform modelului:

$ sed "/test/d" fișierul meu


Ștergerea șirurilor după model

Când apelați d, puteți specifica câteva modele - liniile în care apare modelul și acele linii care se află între ele vor fi șterse:

$ sed "/secunda/,/al patrulea/d" fișierul meu


Eliminarea unui interval de rânduri folosind modele

Inserarea textului într-un flux

Cu sed, puteți insera date într-un flux de text folosind comenzile i și a:
  • Comanda i adaugă o nouă linie înaintea celei date.
  • Comanda a adaugă o nouă linie după cea dată.
Luați în considerare un exemplu folosind comanda i:

$ echo „Un alt test” | sed "i\Primul test"


Echipa i

Acum să aruncăm o privire la comanda a:

$ echo „Un alt test” | sed "a\Primul test"


Echipa a

După cum puteți vedea, aceste comenzi adaugă text înainte sau după datele din flux. Ce se întâmplă dacă trebuie să adăugați o linie undeva la mijloc?

Aici vom fi ajutați prin specificarea numărului liniei de referință din flux, sau a șablonului. Rețineți că adresarea șirurilor ca un interval nu va funcționa aici. Să apelăm comanda i, specificând numărul liniei înaintea căreia dorim să inserăm o nouă linie:

$ sed "2i\Aceasta este linia inserată." Dosarul meu


comand cu numărul liniei de referință

Să facem același lucru cu comanda a:

$ sed "2a\Aceasta este linia atașată." Dosarul meu


Comanda a cu numărul liniei de referință

Observați diferența în modul în care funcționează comenzile i și a. Prima inserează o nouă linie înaintea celei specificate, a doua - după.

Înlocuire șiruri

Comanda c vă permite să modificați conținutul unei linii întregi de text din fluxul de date. Când îl apelați, trebuie să specificați numărul liniei, în loc de care date noi ar trebui adăugate în flux:

$ sed "3c\Aceasta este o linie modificată." Dosarul meu


Înlocuirea unui șir întreg

Dacă folosiți un model sub formă de text simplu sau o expresie regulată atunci când apelați comanda, toate liniile care se potrivesc cu modelul vor fi înlocuite:

$ sed "/Acesta este/c Aceasta este o linie de text schimbată." Dosarul meu


Înlocuirea șirurilor cu un model

Înlocuirea caracterelor

Comanda y operează pe caractere individuale, înlocuindu-le în funcție de datele care i-au fost transmise atunci când este apelată:

$ sed "y/123/567/" fişierul meu


Înlocuirea caracterelor

Când utilizați această comandă, trebuie să țineți cont de faptul că se aplică întregului flux de text, nu o puteți limita la anumite apariții ale caracterelor.

Afișarea numerelor de linii

Dacă apelați sed folosind comanda =, utilitarul va tipări numerele de linie din fluxul de date:

$ sed "=" fișierul meu


Afișarea numerelor de linii

Editorul de flux a scos numerele de rând înaintea conținutului lor.

Dacă treceți un model la această comandă și utilizați opțiunea sed -n, vor fi tipărite numai numerele de linie care se potrivesc cu modelul:

$ sed -n "/test/=" fișierul meu


Afișați numerele de linii care corespund unui model

Citirea datelor pentru a fi inserate dintr-un fișier

Mai sus, am analizat tehnicile de inserare a datelor într-un flux, indicând ce ar trebui să fie inserat, chiar atunci când apelăm sed. De asemenea, puteți utiliza un fișier ca sursă de date. Pentru a face acest lucru, utilizați comanda r, care vă permite să inserați date din fișierul specificat în flux. Când îl apelați, puteți specifica numărul de linie după care doriți să introduceți conținutul fișierului sau un șablon.

Luați în considerare un exemplu:

$ sed "3r nou fișier" fișierul meu


Inserarea conținutului fișierului într-un flux

Aici conținutul fișierului nou a fost inserat după a treia linie a fișierului meu.

Iată ce se întâmplă dacă utilizați un șablon când apelați comanda r:

$ sed "/test/r fişier nou" fişierul meu


Utilizarea unui wildcard la invocarea comenzii r

Conținutul fișierului va fi inserat după fiecare linie care se potrivește cu modelul.

Exemplu

Să ne imaginăm o astfel de sarcină. Există un fișier în care există o anumită secvență de caractere, în sine lipsită de sens, care trebuie înlocuită cu date preluate dintr-un alt fișier. Și anume, să fie un fișier newfile , în care secvența de caractere DATA joacă rolul unui substituent. Datele care urmează să fie înlocuite cu DATE sunt stocate în fișierul de date.

Puteți rezolva această problemă folosind comenzile r și d ale editorului de flux sed:

$ Sed "/DATA>/ ( r nou fișier d)" fișierul meu


Înlocuirea substituentului cu date reale

După cum puteți vedea, în loc de substituentul DATE, sed a adăugat două linii din fișierul de date în fluxul de ieșire.

Rezultate

Astăzi am acoperit elementele de bază ale lucrului cu editorul de flux sed. De fapt, sed este un subiect uriaș. Învățarea acestuia poate fi comparată cu învățarea unui nou limbaj de programare, dar odată ce înțelegeți elementele de bază, puteți stăpâni sed la orice nivel de care aveți nevoie. Drept urmare, capacitatea ta de a procesa texte cu acesta va fi limitată doar de imaginația ta.

Asta e tot pentru azi. Data viitoare vom vorbi despre limbajul de procesare a datelor awk.

Dragi cititori! Folosești sed în munca ta zilnică? Dacă da, vă rugăm să împărtășiți experiența dvs.

Sed este un instrument ușor (binarul cântărește doar 128 de kiloocteți) și un instrument convenabil de procesare a textului.

În acest articol, voi da câteva exemple simple de utilizare sedși vorbește despre principalele sale caracteristici.

Sed preia fluxul de intrare sau fișierul linie cu linie, editează fiecare linie conform regulilor definite în scriptul sed și apoi tipărește rezultatul. Sed este un limbaj de programare complet Turing.

formatul de comandă sed

Comanda sed are formatul:

sed [ -n ] [ -e script ] [ -f fișier script ] [ fișiere ]

Steag -n suprimă ieșirea
-e- indică lista de instrucțiuni date pe linia de comandă.
-f- indică locația fișierului script.

Editați formatul comenzii

Fișierul script constă dintr-un set de comenzi:

[ adresa [ , adresa ] ] comanda [ argumente ]

unul pe linie.
Adresele sunt fie numere de rând, fie caractere speciale, fie o expresie regulată:

$ - ultima linie
începe~N- Fiecare N-a linie, începând cu numărul start
/expresie uzuala/- șiruri care se potrivesc cu expresia_regulară
Exemple:

1~2 - La fiecare a doua linie /REGEXP/- toate liniile care conțin /REGEXP/ 10,20 - linii de la 10 la 20 10,+10 - linii de la 10 la 20 5~N- linii incepand de la a 5-a si pana la prima, multiple N 5, /REGEXP/- linii care conțin /REGEXP/, după a 5-a (fără includere a 5-a)
  • Dacă adresa nu este specificată, toate liniile sunt procesate.
  • Dacă este specificată o adresă, linia corespunzătoare este procesată
  • Dacă sunt specificate două adrese, atunci sunt selectate rândurile din intervalul dat.
  • !echipă- efectuat echipă, pentru rândurile care nu au fost selectate după adresă.

Comenzi de bază

Luați în considerare comenzile de bază:

[adresă] un text- adăugați o nouă linie cu text după linia specificată

$ cat sed_test sed_test_1 11111 sed_test_2 22222 sed_test_3 33333 $ sed -e "2 a new_line" sed_test sed_test_1 11111 sed_test_2 22222 new_line sed_test_3 33333

[adresa [, adresa]] c text- Șterge liniile selectate și le înlocuiește cu text

$ sed -e „2 cu noua linie” sed_test sed_test_1 11111 noua linie sed_test_3 33333 $ sed -e „/3/ cu noua linie” sed_test sed_test_1 11111 sed_test_2 22222 noua linie

[adresa [, adresa]] d- Șterge liniile specificate.

$ sed -e "2 d" sed_test sed_test_1 11111 sed_test_3 33333 $ sed -e "2!d" sed_test sed_test_2 22222

[adresa] i text- Inserează textîn locul liniei specificate.

$ sed -e "2 i new_line" sed_test sed_test_1 11111 text_nou sed_test_2 22222 sed_test_3 33333

[adresa [, adresa]] p(cu steag -n) tipărește liniile găsite.

$ sed -ne "2p" sed_test sed_test_2 22222

[adresa] q- iesire din sed.

[adresă [, adresă]] fișier r- Citeste fişierși scoate conținutul acestuia.

[adresa [, adresa]] s/regex/replacement/flags- Înlocuiește expresie uzuala pe înlocuire-y cu steaguri:

  • g - în toată linia
  • i - insensibil la majuscule
  • p - afișează rezultatul înlocuirii
$ sed -ne "s/t/T/g" sed_test sed_TesT_1 11111 sed_TesT_2 22222 sed_TesT_3 33333 $ sed -e "s//d/g" sed_test sed_test_d ddddd sed_test_d ddddd sed_test_d ddddd

[adresa[, adresa]] y/line1/line2/- Înlocuiește toate aparițiile caracterelor din linia 1 caractere corespunzătoare din liniile 2. Lungimile șirului trebuie să fie aceleași.

$ sed -ne "y/est/EST/g" sed_test SEd_TEST_1 11111 SEd_TEST_2 22222 SEd_TEST_3 33333

[adresa[, adresa]] (comenzi)- paranteze comenzi de grup
[adresa] =- Oferă numere de linie

Etichete

: eticheta- mapare la un grup de comenzi eticheta
eticheta b eticheta, dacă eticheta lipsește, apoi mergeți la sfârșitul fișierului batch.

marca t- sari la comanda indicata de eticheta eticheta numai după o înlocuire cu succes folosind comanda s///

Run bucla

sed funcționează cu două buffere de date: principal și auxiliar. Ambele tampoane sunt inițial goale.
Lucrul cu aceste buffere se face folosind comenzile:\\`h’, `H’, `x’, `g’, `G’ `D’ h- Înlocuiți conținutul buffer-ului auxiliar cu conținutul principal
H- Adăugați o nouă linie la buffer-ul auxiliar și apoi adăugați conținutul buffer-ului principal la conținutul auxiliarului
X- Schimbați conținutul ambelor buffer-uri
g- Înlocuiți conținutul tamponului principal cu conținutul auxiliarului
G- Adăugați o nouă linie la buffer-ul principal și apoi adăugați conținutul buffer-ului auxiliar la conținutul principal
D- Ștergeți textul tampon principal până la următorul caracter de linie nouă
N- Adăugați o linie nouă în buffer-ul principal, apoi adăugați următoarea linie care urmează să fie procesată acolo
P- Ieșiți conținutul buffer-ului principal până la următorul caracter newline.

Exemple mai complexe

Următorul script schimbă liniile unui fișier (primele linii devin ultimele și invers)

$ cat tac.sed #!/usr/bin/sed -nf # începând cu a doua linie, conținutul buffer-ului (care conține deja # toate liniile anterioare) este adăugat la linia curentă. unu! G # când se ajunge la ultima linie, se imprimă $ p # Buffer din nou h sed -nf tac.sed sed_test sed_test_3 33333 sed_test_2 22222 sed_test_1 11111

Citiți rândurile fișierului (afișați numărul ultimei rânduri)

$ cat count.sed #!/usr/bin/sed -nf $=

rezultat

$ sed -nf count.sed sed_test 3

Inversarea șirurilor

$ cat revers.sed #!/usr/bin/sed -f # sări peste rândurile cu o singură literă /../! b # Inversați șirul. Adăugați o linie goală înainte și după cea curentă. s/% [email protected]~*!G4;:%#`.*$/\ &\ / # Mutați primul caracter la sfârșit # bucla rulează atâta timp cât există caractere pe linia din mijloc. tx:x s/\(\\n.\)\(.*\)\(.\\n\)/\\3\\2\\1/ tx #elimină întreruperile de linie suplimentare s/\\n// g

Acest script mută două litere simultan.

$ sed -f revers.sed sed_test 11111 1_tset_des 22222 2_tset_des 33333 3_tset_des

Informații suplimentare

Puteți afla mai multe despre formatul scripturilor sed citind manualul man sed sau documentație tehnică info sed.

Mulți dintre voi probabil ați folosit editorul de text sed stream pentru unele dintre scopurile dvs., dacă nu, voi fi bucuros să vă spun despre asta, voi încerca să fiu mai detaliat. De ce se numește streaming? Răspunsul este simplu - imaginați-vă un document text de intrare care trece prin program și rezultatul este o altă formă a acestui fișier procesată de program. Un fel de mașină de tocat carne - pui carne, pe bază de grilă - obții fie carne tocată, fie altceva.

Deci, implicit, se pare că acest utilitar ar trebui să fie deja pe sistemul dvs. (în cazul meu, îl aveam deja în Debian 7.6), dacă nu, atunci -

Cu text:

parametrul „s” de la început indică faptul că trebuie să înlocuiți textul, g - la sfârșitul textului înlocuit - că trebuie să faceți acest lucru global (pe întregul fișier)

De exemplu, dorim să înlocuim cuvântul Sergey cu Andrey în fișierul text.txt și să încărcăm toate acestea în fișierul textout.txt, acționăm:

sed „s/Sergey/Andrey/g” text . txt > textout . txt

Rezultat:

Dacă doriți să faceți substituții pentru caractere speciale - de exemplu, pentru caracterul &, atunci trebuie să precedați caracterul special. puneți o bară oblică inversă „\” cu un caracter, dacă trebuie să specificați ce trebuie sed pentru a reveni la începutul liniei, este folosit caracterul special „^”. În plus, într-o singură linie puteți scrie 2 sau mai multe modificări, separându-le cu punct și virgulă - „;”. De exemplu, torturăm fișierul textout.txt deja modificat. Mai întâi, voi afișa din nou conținutul actual al fișierului textout.txt:

root @ testhostname : ~ # cat textout.txt

Test pentru Andrey

Testul 2 pentru Andrey

Testul 3 pentru Andrey

Acum introduceți comanda:

sed "s/for/\&/g;s/^Test/Sergey/g" textout . txt > textout2 . txt

Astfel, în locul cuvântului pentru, punem pictograma & (caracterul special se introduce cu simbolul „\” înainte de caracterul special), apoi semnul separator (pentru a scrie toate modificările într-un singur rând de sed’a -> „ ;", în loc de cuvântul de la începutul rândului "Test" pune cuvântul Serghei, rezultatul a ceea ce s-a întâmplat:

Totul așa cum ne-am dorit!

Deci, sed este un bun ajutor atunci când vizualizați jurnalele. De exemplu, trebuie să încărcăm toate rândurile datei de astăzi (să fie 10 octombrie în cazul nostru) din fișierul jurnal /var/log/messages în fișierul testlog.txt, să continuăm:

sed - n "/^Oct 10/ p" / var / log / mesaje > testlog . txt

aici am adăugat parametrul -n, iar apoi - '/^Oct 10/ - adică linia ar trebui să înceapă de la data de 10 octombrie, apoi parametrul p - adică tipărirea (imprimarea conținutului în această condiție), apoi sursa fișierul și fișierul în care aruncăm rezultatele în funcție de starea noastră de filtru, rulați-l, vedeți ce conține fișierul testlog.txt abia pe 10 octombrie:

Excelent! Dacă nu sunt necesare multe linii, dar în mod condiționat este nevoie să luăm doar de la prima la a cincea linie, separăm cererea noastră curentă cu semnul „|” eliminarea încărcării în fișierul testlog.txt și scrierea sed -n 1.5p - ceea ce înseamnă că trebuie să scoatem (p - imprimați la sfârșitul expresiei) de la primul „1” la (separat prin virgulă) al cincilea „5 "linie. În total, obținem ceva de genul acesta:

sed - n "/^Oct 10/ p" / var / jurnal / mesaje | sed - n 1 , 5p > testlog - 5strok.txt

Încă o dată, vă atrag atenția asupra faptului că fișierul în care încărcăm rezultatele a fost mutat până la sfârșit (testlog-5strok.txt), vedem rezultatul acțiunilor noastre: