Grep och sed Demystified

Grep. Du hör det mycket. Du ser de kryptiska IT-killar som skriver kommandot, systemadministratörer som nämner det i förbigående, du ser det ens i vissa skalskript. Det verkar som en av de saker som existerar, men är inte avsedd för dig. Denna artikel kommer att ändra det - vi kommer att förklara och ta en snabb titt på grep (och dess mindre kända vän sed) i den här senaste delen av OS X Demystified.


Introduktion

grep

Grep är ett kommandoradsverktyg för att söka och filtrera någon form av textinmatning baserat på parametrar du matar in

Grep är ett kommandoradsverktyg för att söka och filtrera någon form av textinmatning baserat på parametrar du matar in. Med andra ord går det i terminalen (Program → Verktyg → Terminal) och används exklusivt genom att skriva kommandon. Det finns förstås GUI wrappers som hjälper lite, men ingen är lika kraftfulla eller mångsidiga som användningen av bare benen kommandorads, så det är vad vi ska fokusera på.

Det är bra, men vad gör det egentligen? Lyder det ovanstående för vagt? Här är ett exempel. Säg att du har ett block med text i en fil som heter jungle.txt med fem rader:

En lejon sover i djungeln En lejon sover i natt En tigern vaknar i träsken Parrotet observerar Wimoweh, wimoweh, wimoweh, wimoweh

För att hitta raden som innehåller ordet tiger använder vi grep således:

grep tiger jungle.txt

Resultatet vi får är:

"En tiger vaknar i träsken"

Ok, det är klart, eller hur? Låt oss ta ett steg tillbaka men.

Uppgradering Grep

Som det visar sig Mac grep är långsammare än GNU grep, så låt oss först göra en uppgradering. För att installera ett snabbare grep, skriv följande i Terminal och tryck på stiga på:

brygga installationen https://raw.github.com/Homebrew/homebrew-dupes/master/grep.rb

Observera att du behöver installera Homebrew för att kunna göra det och för att få reda på hur du installerar Homebrew, se min tidigare artikel.

Ett brett utbud av geeklets kommer ofta att lita på grep för att hämta data från stora textfiler eller skördade webbplatser

Vad har vi åstadkommit genom att utföra denna uppgradering? Tja, många appar använder det installerade inbyggda grepverktyget för att fungera. Till exempel kommer ett brett spektrum av geeklets ofta att lita på grep för att hämta data från stora textfiler eller skördade webbplatser. Således, Allt dina grep-using geeklets kommer nu att vara flera gånger snabbare i sina greppy delar. Dessutom kan du ibland behöva greppa någon typ av fellogg (låt oss säga att du har en stor fellogg från ett program och appens supporttjänst berättar att du klistrar in dem "grep port-1723"). Om loggen har miljontals linjer kod kan du spara mycket tid med det här mycket snabbare greppet.

När Homebrew installerar ditt nya grep, försök göra följande om du har gjort filerna. Om inte, fortsätt och gör dem, kör sedan kommandot för att se till att allt fungerar.

grep tiger jungle.txt

Sed

Sed är en stream editor. Ställ helt och hållet, det tar in, redigerar det och matar ut det redigerade innehållet. Oavsett om det redigeras i en fil eller matas direkt från Terminal, är det helt irrelevant för sed - det har en mycket avancerad och konfigurerbar funktion och utför den så gott som möjligt.

Sed tar lite textinmatning, ett kommando på hur man ändrar det och producerar ändrad utskrift

Så var används sed? Redigering av filinnehåll och liknande, förstås, men det händer bara att det fungerar felfritt hand i hand med grep. Låt oss se några rena sed exempel först. Skriv följande i Terminal:

echo "Hej"

och tryck på enter. Terminalen säger hej. Skriv nu

eko "Hej" | sed 's / Hell / Heaven /'

och tryck på enter. Du borde se "Heaveno". Vad hände nyss? Se, sed fungerar genom att ta två argument. Den första är matningen, ingången och den andra är en sträng (du kan se att det är en sträng eftersom den är citerad) som berättar vilka åtgärder som ska utföras vid det första argumentet. I vårt fall är det:

  • s (ersättare)
  • / (avgränsare - i vårt fall framåtstreck, se nästa stycke för alternativ)
  • Helvete (regelbundet uttrycksmönster för att söka efter)
  • Heaven (ersättningssträng)

Det andra listobjektet nämner alternativ till framåtskärningsavgränsaren; ibland kommer de att vara mycket praktiska på grund av att man till exempel skriver URL eller filvägar. Ta till exempel webbadressen myfolder / mysubfolder / minfil. Om vi ​​sätter detta i sed för att ersätta det med myotherfolder / myotherfile, parametern skulle se ut så här: s / myfolder / mysubfolder / minfil / myotherfolder / myotherfile / som bara är en stor väska med nonsens - sed kan inte få veta vilken av de här fragmenten är regexp och vilken är ersättningssträngen. Därför skulle vi behöva fly Framsteg i vår filepath med backslash, så varje framåtblick i banan skulle bli till \ /. Jag gissar att du kan se problemet. Den nya sed-parametern ser ut så här:

sed / myfolder \ / mysubfolder \ / myfile / myotherfolder \ / myotherfile / '

Detta knappt läsbara format kallas ett "staketet" och för att undvika det, stödjer sed olika avgränsare som understrykning (_), kolon (:) och pip (|). Om vi ​​till exempel vill använda rörtecken som avgränsare skulle vi sluta med följande:

sed 's | myfolder / mysubfolder / myfile | myotherfolder / myotherfile |'

Mycket bättre, nej?

En annan sak, dock. Vi sa att sed tar två argument, men vi ger det bara en gång - strax efter sed kommando. Detta beror på rörets karaktär efter vårt eko kommando. Röret tjänar som ett medel att rikta utmatningen från vänster operand till ingången på den högra operanden. I vårt fall berättade rörteckenet sed program "Ta som input vad som än är det du får från vad som helst på vänster sida av mig". sed har ingen aning om att det handlar om eko ​​- det behöver inte veta. Allt det vet är att det tar textinmatning. Att diskutera rörledningen mer detaljerat än detta ligger utanför ramen för denna artikel, men gärna läsa om du är intresserad.

Röret tjänar som ett medel att rikta utmatningen från vänster operand till ingången på den högra operanden.

Så hur kombinerar vi det med grep? Det är exakt detsamma. Med vårt tidigare exempel, låt oss ange följande i terminalen.

grep tiger jungle.txt | sed 's / swamp / desert /'

och vi får utmatningen

"En tiger vaknar i öknen"

Låt oss nu titta på en verklig världssituation.


Real World Application

För vår "dissektion" tar vi grep + sed-kommandot av en populär väderkropp och förklarar det bit för bit. Gå vidare och ladda ner provkroppen. När den är nedladdad, öppna den med en textredigerare av något slag. Du märker att det inte är mer än en XML-fil. Om du inte har någon erfarenhet av XML, var inte rädd - Josh gjorde redan en fantastisk artikel om Geektool och dess ins och outs. Vi kommer inte att ta itu med nitty gritty av allt idag. Låt oss istället fokusera på delen mellan tags:

 curl - silent "http://xml.weather.yahoo.com/forecastrss?w=28348727&u=c" | grep -E '(Nuvarande förhållanden: | C// '-e s /// '-e s /<\/b>// '-e s /
// '-e' s /// '-e s /<\/description>//'

Denna kryptiska röra är ett enkelt Terminal-kommando - inget mer. Du kan även klistra in det i Terminal och du får väderförhållandena för Makati City i Filippinerna, som den ursprungliga författaren satte den att hämta. Geeklet berättar Geektool att köra kommandot och ta vad som helst som det blir genom att köra det. Låt oss ta en titt på det, rörsegmentet genom rörsegmentet och förklara i detalj:

curl - silent "http://xml.weather.yahoo.com/forecastrss?w=28348727&u=c"

ringla är ett verktyg för överföring av data med en URL-syntax. Det betyder att det kan gå till en URL och hämta data från den.

Curl är ett verktyg som används för att överföra data med en URL-syntax på kommandoraden

Om du klistrar in den citerade URL-adressen i din webbläsare (eller bara klicka här) märker du att du får en XML-fil från Yahoo! - De har en live väderförhållande tjänst som du enkelt kan komma åt och hämta data från. Det här är exakt samma sak som du får när du ringla Det; Endast i stället för webbläsaren skickas inmatningen till Terminal. De --tyst flaggan berättar att det är tyst om framsteg, status och fel, så att den enda produktionen vi får är den produktion vi behöver (eller ingenting om det misslyckas).

grep -E '(Nuvarande förhållanden: | C 

Rörkaraktären följer, vilket betyder produktionen från ringla skickas till grep som inmatning. Grep tar emot den nedladdade XML-filen i textformat och kör en sökning på den med -E flagga, vilket betyder Extended Regular Expression. Värdet det söker är antingen strängen Nuvarande omständigheter: eller C (röret karaktär inuti en ereg betyder "eller"). För ytterligare förtydligande, om du skrev följande i vårt tidigare exempel:

grep -E '(tiger | weh)' jungle.txt

du skulle få

En tiger vaknar i träsken Wimoweh, wimoweh, wimoweh, wimoweh

eftersom det returnerar alla rader som innehåller antingen "tiger" eller "weh".

Så om vi kör dessa två första rörsegment tillsammans som så:

curl - silent "http://xml.weather.yahoo.com/forecastrss?w=28348727&u=c" | grep -E '(Nuvarande förhållanden: | C 

vi får följande:

Nuvarande omständigheter:
Haze, 23 C

Men vi vill bara få "Haze, 23 C". Det är här sed kommer in. Vi ersätter helt enkelt vad vi inte vill ha med en tom sträng (ingenting) på ett effektivt sätt.

sed-s / Nuvarande förhållanden: // '-e s /
// '-e s /// '-e s /<\/b>// '-e s /
// '-e' s /// '-e s /<\/description>//'

De -e flaggan är förkortad --expression = och tillåter oss att kedja flera sed kommandon. Därför ersätter vi först strängen "Nuvarande förhållanden:" med ingenting, följt av att ersätta
med ingenting etc. tills vi når den möjliga änden av linjen ().

Till sist är allt som är kvar "Haze, 23 C".

Jag borde nämna att nålen som vi har använt som ett exempel kunde ha blivit mycket bättre, men den kommande kommandos rena komplexitet verkade som en mycket bra möjlighet att täcka flera exempel på en gång. Författaren kunde till exempel ha hämtat linjen som innehåller "Aktuella förhållanden:" och raden efter det med -A 1 flaggan kombination, utan att förlita sig på temperatur symbolen (i det här fallet litar vi på Celsius, men vad om vi ville ha Fahrenheit? Författarens C grep-sökning skulle misslyckas). Men exemplet tjänade ett syfte - och det var att introducera dig till den underbara världen av grep och sed.


Fler resurser

Medan du lär dig avancerade reguljära uttryck och djupare grep är curl och sed-funktionaliteten långt ifrån denna artikels (och den här webbplatsens) räckvidd, gärna titta på följande resurser om du vill veta mer.

  • Sed guide
  • Nybörjarens guide till grep
  • Praktiska Unix Grep Command-exempel
  • Grep dokumentation hos IBM
  • Curl dokumentation
  • Vanliga uttryck

Slutsats

Du vet nu grunderna i grep, sed och även ringla. Medan denna kraschbana var långt ifrån för att göra dig till en expert hoppas vi att det var minst tillräckligt för att få dig att intressera dig för att försöka din egen datainsamling och förfrågan. Det är åtminstone något att prata om runt vattenkylaren på måndag.

Jag hoppas att du njöt av det, och om du är ute efter en utmaning, försök att skriva om Geeklet för att inte bara vara agnostisk temperatur symbol, utan också ta reda på användarens plats utan att manuellt ändra "w "parameter i Yahoo! URL.