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 /
: Elsed
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 fitxersed
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 asegon 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 PARTIDA
, G; 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.