Com s'utilitza l'ordre sed a Linux

Pot semblar una bogeria, però el Linux sed comando és un editor de text sense interfície. Podeu utilitzar-lo des de la línia d'ordres per manipular text en fitxers i fluxos. Us mostrarem com aprofitar el seu poder.

El poder del sed

El sed comando és una mica com els escacs: es necessita una hora per aprendre els conceptes bàsics i tota la vida per dominar-los (o, almenys, molta pràctica). Us mostrarem una selecció de gambits d’obertura en cadascuna de les categories principals de sed funcionalitat.

sed és un editor de flux que funciona amb entrades canalitzades o fitxers de text. Tanmateix, no té una interfície interactiva d’editor de text. Més aviat, proporcioneu instruccions perquè segueixi mentre funciona pel text. Tot això funciona a Bash i altres intèrprets de línia de comandes.

Amb sed podeu fer tot el següent:

  • Seleccioneu text
  • Text substitutiu
  • Afegiu línies al text
  • Suprimiu les línies del text
  • Modifiqueu (o conserveu) un fitxer original

Hem estructurat els nostres exemples per introduir i demostrar conceptes, no per produir el més tersest (i menys accessible) sed ordres. Tanmateix, les funcions de concordança de patrons i selecció de text de sed confieu en gran mesura en expressions regulars (regexes). Necessiteu una certa familiaritat amb aquests per treure el màxim partit sed.

RELACIONATS:Com s'utilitzen expressions regulars (regexs) a Linux

Un exemple senzill

En primer lloc, farem servir ressò per enviar text a sed per una canonada, i tenir sed substituïu una part del text. Per fer-ho, escrivim el següent:

eco howtogonk | sed 's / gonk / geek /'

El ressò ordre envia "howtogonk" a sed, i s'aplica la nostra regla de substitució simple (la "s" significa substitució).sed cerca al text d’entrada una ocurrència de la primera cadena i substituirà qualsevol coincidència per la segona.

La cadena "gonk" se substitueix per "geek" i la nova cadena s'imprimeix a la finestra del terminal.

Les substitucions són probablement l’ús més habitual de sed. Abans de aprofundir en les substitucions, però, hem de saber seleccionar i fer coincidir el text.

Selecció de text

Necessitarem un fitxer de text per als nostres exemples. En farem servir un que contingui una selecció de versos del poema èpic de Samuel Taylor Coleridge "The Rime of the Ancient Mariner".

Escrivim el següent per fer-hi una ullada menys:

menys coleridge.txt

Per seleccionar algunes línies del fitxer, proporcionem les línies inicial i final de l'interval que volem seleccionar. Un sol número selecciona aquesta línia.

Per extreure les línies d'una a quatre, escrivim aquesta ordre:

sed -n '1,4p' coleridge.txt

Tingueu en compte la coma entre 1 i 4. El pàg significa "imprimir línies coincidents". Per defecte,sed imprimeix totes les línies. Veuríem tot el text del fitxer amb les línies coincidents impreses dues vegades. Per evitar-ho, utilitzarem el fitxer -n (silenciosa) opció per suprimir el text sense igual.

Canviem els números de línia perquè puguem seleccionar un vers diferent, com es mostra a continuació:

sed -n '6,9p' coleridge.txt

Podem utilitzar el -e (expressió) opció per fer diverses seleccions. Amb dues expressions, podem seleccionar dos versos:

sed -n -e '1,4p' -e '31, 34p 'coleridge.txt

Si reduïm el primer número a la segona expressió, podem inserir un espai entre els dos versos. Escrivim el següent:

sed -n -e '1,4p' -e '30, 34p 'coleridge.txt

També podem triar una línia de sortida i dir-ho sed per passar pel fitxer i imprimir línies alternatives, cada cinquena línia, o saltar qualsevol nombre de línies. L'ordre és similar als que hem utilitzat anteriorment per seleccionar un interval. Aquesta vegada, però, utilitzarem un títol (~) en lloc d'una coma per separar els nombres.

El primer número indica la línia de sortida. El segon número ho explica sed quines línies després de la línia inicial volem veure. El número 2 significa cada segona línia, 3 significa cada tercera línia, etc.

Escrivim el següent:

sed -n '1 ~ 2p' coleridge.txt

No sempre sabreu on es troba el fitxer que busqueu, de manera que els números de línia no sempre ajudaran. Tanmateix, també podeu utilitzar-lo sed per seleccionar línies que continguin patrons de text coincidents. Per exemple, extraiem totes les línies que comencin per "I".

El cursor (^) representa l’inici de la línia. Inclourem el nostre terme de cerca en barres inclinades (/). També incloem un espai després de "I", de manera que paraules com "Android" no s'inclouran al resultat.

Lectura sed els scripts poden ser una mica difícils al principi. El / pàg significa "imprimir", tal com ho feia a les ordres que hem utilitzat més amunt. Tanmateix, a l'ordre següent hi ha una barra inclinada cap endavant:

sed -n '/ ^ And / p' coleridge.txt

Tres línies que comencen amb “I” s’extreuen del fitxer i es mostren per a nosaltres.

Fer substitucions

En el nostre primer exemple, us vam mostrar el següent format bàsic per a sed substitució:

eco howtogonk | sed 's / gonk / geek /'

El s explica sed això és una substitució. La primera cadena és el patró de cerca i la segona és el text amb el qual volem substituir aquest text coincident. Per descomptat, com passa amb totes les coses de Linux, el diable està en els detalls.

Escrivim el següent per canviar totes les ocurrències de "dia" a "setmana" i donar al mariner i a l'albatros més temps per vincular-se:

sed -n 's / dia / setmana / p' coleridge.txt

A la primera línia, només es canvia la segona ocurrència de "dia". Això és perquè sed s’atura després del primer partit per línia. Hem d’afegir una “g” al final de l’expressió, com es mostra a continuació, per fer una cerca global de manera que es processin totes les coincidències de cada línia:

sed -n '/ dia / setmana / gp' coleridge.txt

Això coincideix amb tres dels quatre de la primera línia. Perquè la primera paraula és "Dia" i sed distingeix entre majúscules i minúscules, no considera que aquesta instància sigui la mateixa que "dia".

Escrivim el següent, afegint un jo a l'ordre al final de l'expressió per indicar insensibilitat entre majúscules i minúscules:

sed -n 's / dia / setmana / gip' coleridge.txt

Això funciona, però és possible que no sempre vulgueu activar la insensibilitat a majúscules i minúscules per a tot. En aquests casos, podeu utilitzar un grup d'expressió regular per afegir insensibilitat a majúscules i minúscules específica del patró.

Per exemple, si adjuntem caràcters entre claudàtors ([]), s’interpreten com “qualsevol personatge d’aquesta llista de personatges”.

Escrivim el següent i incloem "D" i "d" al grup, per garantir que coincideixi tant amb "Dia" com amb "dia":

sed -n 's / [Dd] ay / week / gp' coleridge.txt

També podem restringir les substitucions a seccions del fitxer. Suposem que el nostre fitxer conté espaiats estranys al primer vers. Podem utilitzar l'ordre familiar següent per veure el primer vers:

sed -n '1,4p' coleridge.txt

Cercarem dos espais i els substituirem per un. Ho farem a nivell mundial perquè l'acció es repeteixi a tota la línia. Per ser clar, el patró de cerca és l’espai, l’asterisc espacial (*), i la cadena de substitució és un espai únic. El 1,4 restringeix la substitució a les quatre primeres línies del fitxer.

Ho combinem tot amb l'ordre següent:

sed -n '1,4 s / * / / gp' coleridge.txt

Això funciona molt bé. El patró de cerca és l’important aquí. L'asterisc (*) representa zero o més del caràcter anterior, que és un espai. Per tant, el patró de cerca busca cadenes d’un espai o més.

Si substituïm un sol espai per qualsevol seqüència de diversos espais, tornarem el fitxer a espaiat regular, amb un únic espai entre cada paraula. Això també substituirà un sol espai per un sol espai en alguns casos, però això no afectarà res negativament, encara obtindrem el resultat desitjat.

Si escrivim el següent i reduïm el patró de cerca a un sol espai, veureu immediatament per què hem d’incloure dos espais:

sed -n '1,4 s / * / / gp' coleridge.txt

Com que l'asterisc coincideix amb zero o més del caràcter anterior, veu cada caràcter que no és un espai com un "espai zero" i li aplica la substitució.

Tanmateix, si incloem dos espais al patró de cerca,sed ha de trobar almenys un caràcter espacial abans d'aplicar la substitució. Això garanteix que els caràcters no espacials es mantinguin intactes.

Escrivim el següent, utilitzant el fitxer -e (expressió) que hem utilitzat anteriorment, cosa que ens permet fer dues o més substitucions simultàniament:

sed -n -e 's / motion / flutter / gip' -e 's / ocean / gutter / gip' coleridge.txt

Podem aconseguir el mateix resultat si fem servir un punt i coma (;) per separar les dues expressions, així:

sed -n '/ motion / flutter / gip; s / ocean / gutter / gip' coleridge.txt

Quan vam canviar "dia" per "setmana" a l'ordre següent, també es va canviar la instància de "dia" a l'expressió "bé un dia":

sed -n 's / [Dd] ay / week / gp' coleridge.txt

Per evitar-ho, només podem intentar substituir línies que coincideixin amb un altre patró. Si modifiquem l’ordre per tenir un patró de cerca al principi, només considerarem operar en línies que coincideixin amb aquest patró.

Escrivim el següent per fer del nostre patró coincident la paraula "després":

sed -n '/ after / s / [Dd] ay / week / gp' coleridge.txt

Això ens dóna la resposta que volem.

Substitucions més complexes

Fem un descans i ús a Coleridge sed per extreure noms del fitxer etc / passwd dossier.

Hi ha maneres més curtes de fer-ho (més detalls més endavant), però farem servir el camí més llarg aquí per demostrar un altre concepte. Tots els elements coincidents en un patró de cerca (anomenats subexpressions) es poden numerar (fins a un màxim de nou elements). A continuació, podeu utilitzar aquests números al vostre fitxersed ordres per fer referència a subexpressions específiques.

Cal incloure la subexpressió entre parèntesis [()] perquè això funcioni. Els parèntesis també han d'anar precedits d'una barra inclinada cap enrere (\) per evitar que es tractin com un personatge normal.

Per fer-ho, escriviu el següent:

sed 's / \ ([^:] * \). * / \ 1 /' / etc / passwd

Desglossem això:

  • sed 's /: El sed i el començament de l'expressió de substitució.
  • \(: El parèntesi inicial [(] adjuntant la subexpressió, precedida d'una barra invertida (\).
  • [^:]*: La primera subexpressió del terme de cerca conté un grup entre claudàtors. El cursor (^) significa "no" quan s'utilitza en un grup. Un grup significa qualsevol personatge que no sigui un còlon (:) s’acceptarà com a partit.
  • \): El parèntesi final [)] amb una barra invertida anterior (\).
  • .*: Aquesta segona subexpressió de cerca significa "qualsevol caràcter i qualsevol nombre d'ells".
  • /\1: La part de substitució de l'expressió conté 1 precedit per una barra invertida (\). Representa el text que coincideix amb la primera subexpressió.
  • /': La barra de tancament cap endavant (/) i cometes simples (') finalitzeu el fitxer sed comandament.

El que significa tot això és que buscarem qualsevol cadena de caràcters que no contingui dos punts (:), que serà la primera instància de text coincident. Llavors, cerquem qualsevol altra cosa en aquesta línia, que serà la segona instància de text coincident. Substituirem tota la línia pel text que coincideix amb la primera subexpressió.

Cada línia del fitxer / etc / passwd El fitxer comença amb un nom d'usuari finalitzat per dos punts. Ho coincidim tot fins al primer punt i, a continuació, substituïm aquest valor per tota la línia. Per tant, hem aïllat els noms d’usuari.

A continuació, inclourem la segona subexpressió entre parèntesis [()], de manera que també podem referenciar-lo per número. També el substituirem \1 amb \2. El nostre comandament ara substituirà tota la línia amb tot des del primer punt (:) fins al final de la línia.

Escrivim el següent:

sed 's / \ ([^:] * \) \ (. * \) / \ 2 /' / etc / passwd

Aquests petits canvis inverteixen el significat de l'ordre i obtenim tot excepte els noms d'usuari.

Ara fem una ullada a la manera ràpida i senzilla de fer-ho.

El nostre terme de cerca és del primer còlon (:) fins al final de la línia. Com que la nostra expressió de substitució és buida (//), no substituirem el text coincident per res.

Per tant, escrivim el següent, tallant tot des del primer còlon (:) al final de la línia, deixant només els noms d'usuari:

sed 's /:.*// "/ etc / passwd

Vegem un exemple en què fem referència a la primera i a la segona coincidència en la mateixa ordre.

Tenim un fitxer de comes (,) separant el nom i el cognom. Volem enumerar-los com a "cognom, nom". Podem utilitzargat, tal com es mostra a continuació, per veure què hi ha al fitxer:

cat geeks.txt

Com moltes sed ordres, aquest següent pot semblar impenetrable al principi:

sed 's / ^ \ (. * \), \ (. * \) $ / \ 2, \ 1 / g' geeks.txt

Aquesta és una ordre de substitució com les altres que hem utilitzat i el patró de cerca és bastant fàcil. A continuació, el desglossem:

  • sed 's /: L'ordre de substitució normal.
  • ^: Com que el cursor no està en un grup ([]), significa "L'inici de la línia".
  • \(.*\),: La primera subexpressió és qualsevol nombre de caràcters. Està entre parèntesis [()], cadascun dels quals va precedit d'una barra invertida (\) de manera que podem referenciar-lo per número. Tot el nostre patró de cerca fins ara es tradueix com a cerca des del principi de la línia fins a la primera coma (,) per a qualsevol nombre de caràcters.
  • \(.*\): La següent subexpressió és (de nou) qualsevol nombre de qualsevol caràcter. També està entre parèntesis [()], ambdues precedides d'una barra invertida (\), de manera que podem fer referència al text coincident per número.
  • $/: El signe del dòlar ($) representa el final de la línia i permetrà que la nostra cerca continuï fins al final de la línia. Ho hem utilitzat simplement per introduir el signe del dòlar. Realment no el necessitem aquí, ja que l’asterisc (*) aniria al final de la línia en aquest escenari. La barra inclinada cap endavant (/) completa la secció de patró de cerca.
  • \ 2, \ 1 / g ': Com que hem inclòs les nostres dues subexpressions entre parèntesis, podem referir-nos a totes dues pel seu nombre. Com que volem invertir l'ordre, els escrivim com a segon partit, primer partit. Els números han d'anar precedits d'una barra invertida (\).
  • / g: Això permet que la nostra comanda funcioni globalment en cada línia.
  • geeks.txt: El fitxer en què estem treballant.

També podeu utilitzar l’ordre Cut (c) per substituir línies senceres que coincideixin amb el vostre patró de cerca. Escrivim el següent per cercar una línia amb la paraula "coll" i substituir-la per una nova cadena de text:

sed '/ neck / c Al voltant del meu canell estava enfilat' coleridge.txt

La nostra nova línia apareix a la part inferior del nostre extracte.

Inserció de línies i text

També podem inserir línies i text nous al nostre fitxer. Per inserir línies noves després de les coincidents, utilitzarem l’ordre Add (a).

Aquí teniu el fitxer amb el qual treballarem:

cat geeks.txt

Hem numerat les línies perquè sigui una mica més fàcil de seguir.

Escrivim el següent per cercar línies que continguin la paraula "Ell" i inserim una línia nova a sota:

sed '/ He / a -> Inserit!' geeks.txt

Escrivim el següent i incloem l'ordre Insereix (jo) per inserir la nova línia a sobre de les que contenen text coincident:

sed '/ He / i -> Inserit!' geeks.txt

Podem fer servir l’ampersand (&), que representa el text original coincident, per afegir text nou a una línia coincident. \1 , \2, etc., representen subexpressions coincidents.

Per afegir text a l'inici d'una línia, utilitzarem una ordre de substitució que coincideixi amb tot el que hi ha a la línia, combinada amb una clàusula de substitució que combina el text nou amb la línia original.

Per fer tot això, escrivim el següent:

sed 's /.*/--> Inserit & /' geeks.txt

Escrivim el següent, inclòs el G , que afegirà una línia en blanc entre cada línia:

sed 'G' geeks.txt

Si voleu afegir dues o més línies en blanc, podeu utilitzar-les BONA PARTIDAG; G; G, etcètera.

Supressió de línies

L'ordre Delete (d) suprimeix les línies que coincideixen amb un patró de cerca o les especificades amb números o intervals de línia.

Per exemple, per suprimir la tercera línia, escriuríem el següent:

sed '3d' geeks.txt

Per suprimir l'interval de línies de quatre a cinc, escriuríem el següent:

sed '4,5d' geeks.txt

Per suprimir línies fora d’un interval, fem servir un signe d’exclamació (!), com es mostra a continuació:

sed '6,7! d' geeks.txt

Desant els vostres canvis

Fins ara, tots els nostres resultats s’han imprès a la finestra del terminal, però encara no els hem desat enlloc. Per fer-los permanents, podeu escriure els canvis al fitxer original o redirigir-los a un de nou.

Per sobreescriure el fitxer original cal tenir precaució. Si el teu sed La comanda és incorrecta, és possible que feu alguns canvis al fitxer original que siguin difícils de desfer.

Per una mica de tranquil·litat, sed pot crear una còpia de seguretat del fitxer original abans que executi el seu comandament.

Podeu utilitzar l’opció In-place (-i) contarsed per escriure els canvis al fitxer original, però si hi afegiu una extensió de fitxer, sed farà una còpia de seguretat del fitxer original en un de nou. Tindrà el mateix nom que el fitxer original, però amb una nova extensió de fitxer.

Per demostrar-ho, buscarem les línies que continguin la paraula "Ell" i les suprimirem. També farem una còpia de seguretat del fitxer original en un de nou mitjançant l’extensió BAK.

Per fer tot això, escrivim el següent:

sed -i'.bak '' /^.*He.*$/d 'geeks.txt

Escrivim el següent per assegurar-nos que el nostre fitxer de còpia de seguretat no canvia:

cat geeks.txt.bak

També podem escriure el següent per redirigir la sortida a un fitxer nou i aconseguir un resultat similar:

sed -i'.bak '' /^.*He.*$/d 'geeks.txt> new_geeks.txt

Fem servir gat per confirmar que els canvis s'han escrit al fitxer nou, tal com es mostra a continuació:

cat new_geeks.txt

Havent sed tot això

Com és probable que hàgiu observat, fins i tot aquest manual ràpid sed és bastant llarg. Hi ha moltes coses en aquesta ordre i encara hi podeu fer més.

Amb sort, però, aquests conceptes bàsics han proporcionat una base sòlida sobre la qual es pot construir a mesura que es continua aprenent més.