Nybegynners Guide til Shell Scripting 2: For Loops

Innholdsfortegnelse:

Nybegynners Guide til Shell Scripting 2: For Loops
Nybegynners Guide til Shell Scripting 2: For Loops

Video: Nybegynners Guide til Shell Scripting 2: For Loops

Video: Nybegynners Guide til Shell Scripting 2: For Loops
Video: Дневник хранящий жуткие тайны. Переход. Джеральд Даррелл. Мистика. Ужасы - YouTube 2024, April
Anonim
Hvis du vil bygge opp geekkreditten din, kan du bli med på den andre avgiften i vår skriptserie. Vi har noen rettelser, noen forbedringer til forrige ukes skript, og en veiledning om looping for uinitiert.
Hvis du vil bygge opp geekkreditten din, kan du bli med på den andre avgiften i vår skriptserie. Vi har noen rettelser, noen forbedringer til forrige ukes skript, og en veiledning om looping for uinitiert.

Datecp Script Revisited

I den første delen av Shell Script Guide har vi laget et skript som kopierte en fil til en sikkerhetskatalog etter å ha lagt til datoen til slutten av filnavnet.

Samuel Dionne-Riel påpekte i kommentarene at det er en mye bedre måte å håndtere våre variable referanser på.

Arguments are space-separated in the bash shell, it will tokenize when there is a space in the resulted expanded command. In your script,

cp $1 $2.$date_formatted

vil fungere som ønsket så lenge de utvidede variablene ikke har mellomrom i dem. Hvis du ringer skriptet ditt på denne måten:

datecp 'my old name' 'my new name'

utvidelsen vil resultere i denne kommandoen:

cp my new name my old name.the_date

som faktisk har 6 argumenter.

For å løse dette problemet riktig må den siste linjen i skriptet være:

cp '$1' '$2.$date_formatted'

Som du kan se, endrer vi skriptets linje fra:

cp -iv $1 $2.$date_formatted

til:

cp -iv “$1” “$2”.$date_formatted

vil ta vare på dette problemet når du bruker skriptet på filer som har mellomrom i navnet. Samuel gjør også poenget at når du kopierer og limer koden fra dette nettstedet (eller Internett generelt), må du erstatte de riktige bindestreker og sitater for de "typografisk bedre" de som ofte erstatter dem. Vi vil også gjøre mer for å sikre at vår kode er mer kopi / lim inn vennlig.;-)

En annen kommentator, Myles Braithwaite, bestemte seg for å utvide vårt skript slik at datoen skulle vises før filtypen. Så i stedet for

tastyfile.mp3.07_14_11-12.34.56

vi ville få dette:

tastyfile.07_14_11-12.34.56.mp3

som ender opp med å være litt mer praktisk for de fleste brukere. Koden hans er tilgjengelig på hans GitHub-side. La oss se på hva han bruker for å trekke ut filnavnet.

date_formatted=$(date +%Y-%m-%d_%H.%M%S) file_extension=$(echo “$1″|awk -F. ‘{print $NF}’) file_name=$(basename $1.$file_extension)

cp -iv $1 $file_name-$date_formatted.$file_extension

Jeg har endret formateringen litt, men du kan se at Myles erklærer sin datoperiode i Linje 1. I linje 2 bruker han imidlertid "echo" -kommandoen med det første argumentet for manuset for å utdatere filens navn. Han bruker pipekommandoen til å ta utgangen og bruke den som input for neste del. Etter røret kaller Myles "awk" kommandoen, som er et kraftig mønster skanningsprogram. Ved å bruke -F-flagget, forteller han kommandoen at neste tegn (etter et mellomrom) er det som vil definere "feltavskiller". I dette tilfellet er det en periode.

Nå, awk se en fil kalt "tastyfile.mp3" som består av to felt: "tastyfile" og "mp3". Til slutt bruker han

‘{print $NF}’

for å vise det siste feltet. Hvis filen din har flere perioder - dermed gjør awk, se flere felt - det vil bare vise den siste, som er filtypen.

I linje 3 oppretter han en ny variabel for filens navn og bruker "basename" -kommandoen til å referere alt i $ 1 unntatt filtypen. Dette gjøres ved å bruke basenavn og gi den $ 1 som argument, og deretter legge til et mellomrom og filtypen. Filutvidelsen legges automatisk til på grunn av variabelen som refererer til linje 2. Hva dette ville gjøre er å ta

tastyfile.mp3

og slå den inn i

tastyfile

Så i siste linje, Myles sette sammen kommandoen som vil output alt i orden. Merk at det ikke er noen referanse til $ 2, et annet argument for skriptet. Dette bestemte skriptet vil kopiere filen til din nåværende katalog i stedet. Flott jobb Samuel og Myles!

Kjører skript og $ PATH

Vi nevner også i vår Grunnleggende artikkel at skript ikke har lov til å bli referert som kommandoer som standard. Det vil si at du må peke på skriptets bane for å kunne kjøre den:

./script

~/bin/script

Men ved å plassere skriptene i ~ / bin /, kan du bare skrive navnene deres hvor som helst for å få dem til å løpe.

Kommentarere brukte litt tid på å diskutere hvor riktig dette var, da ingen moderne Linux distro oppretter den katalogen som standard. Videre legger ingen heller den til $ PATH-variabelen som standard, hvilket er det som kreves for at skriptene skal bli kjørt som kommandoer. Jeg var litt forvirret fordi etter å ha sjekket min $ PATH-variabel, var kommentatorene riktige, men ringer skript fungerte fortsatt for meg. Jeg fant ut hvorfor: mange moderne Linux distros lager en spesiell fil i brukerens hjemmekatalog -.profile.

Denne filen leses av bash (med mindre.bash profile er til stede i brukerens hjemmekatalog) og nederst er det en del som legger til ~ / bin / mappen til $ PATH-variabelen hvis den eksisterer. Så, det mysteriet er oppklaret. For resten av serien fortsetter jeg å plassere skript i ~ / bin / katalog fordi de er brukerskript og skal kunne drives av brukere. Og det virker som om vi ikke virkelig trenger å rote med $ PATH-variabelen for hånd for å få ting til å fungere.
Denne filen leses av bash (med mindre.bash profile er til stede i brukerens hjemmekatalog) og nederst er det en del som legger til ~ / bin / mappen til $ PATH-variabelen hvis den eksisterer. Så, det mysteriet er oppklaret. For resten av serien fortsetter jeg å plassere skript i ~ / bin / katalog fordi de er brukerskript og skal kunne drives av brukere. Og det virker som om vi ikke virkelig trenger å rote med $ PATH-variabelen for hånd for å få ting til å fungere.

Gjenta kommandoer med løkker

La oss komme til et av de mest nyttige verktøyene i geek arsenalen for å håndtere repeterende oppgaver: sløyfer. I dag skal vi diskutere "for" looper.

Den grunnleggende oversikten over en forløp er som følger:

for VARIABLE in LIST; do command1 command2 … commandn done

VARIABLE kan være en hvilken som helst variabel, men oftest er små bokstaver "jeg" brukt etter konvensjon. LIST er en liste over elementer; Du kan angi flere elementer (skille dem med mellomrom), peke på en ekstern tekstfil, eller bruk en stjerne (*) for å angi hvilken som helst fil i gjeldende katalog. Kommandoene som er oppført er innrammet etter konvensjon, så det er lettere å se hekker - setter sløyfer i sløyfer (slik at du kan loop mens du slår).

Fordi lister bruker mellomrom som avgrensninger - det vil si et mellomrom betyr et trekk til neste element i listen - filer som har mellomrom i navnet er ikke så vennlige. For nå, la oss holde oss til å jobbe med filer uten mellomrom. La oss starte med et enkelt skript for å vise navnene på filene i gjeldende katalog. Opprett et nytt skript i din ~ / bin / folder med tittelen "loopscript". Hvis du ikke husker hvordan du gjør dette (inkludert merking av det som kjørbar og legger til hash bang hack), se vår bash scripting grunnleggende artikkel.

I den oppgir du følgende kode:

for i in item1 item2 item3 item4 item5 item6; do echo “$i” done

Når du kjører skriptet, bør du bare få disse listepostene som utgang.
Når du kjører skriptet, bør du bare få disse listepostene som utgang.
Ganske enkelt, ikke sant? La oss se hva som skjer hvis vi forandrer ting litt. Endre skriptet ditt slik at det står dette:
Ganske enkelt, ikke sant? La oss se hva som skjer hvis vi forandrer ting litt. Endre skriptet ditt slik at det står dette:

for i in *; do echo “$i” done

Når du kjører dette skriptet i en mappe, bør du få en liste over filer som den inneholder som utgang.
Når du kjører dette skriptet i en mappe, bør du få en liste over filer som den inneholder som utgang.
La oss nå endre ekkokommandoen til noe mer nyttig - si zip-kommandoen. Nemlig legger vi til filer i et arkiv. Og, la oss få noen argumenter i blandingen!
La oss nå endre ekkokommandoen til noe mer nyttig - si zip-kommandoen. Nemlig legger vi til filer i et arkiv. Og, la oss få noen argumenter i blandingen!

for i in $@; do zip archive “$i” done

Det er noe nytt! "$ @" Er en snarvei for "$ 1 $ 2 $ 3 … $ n". Med andre ord er det en fullstendig liste over alle argumenter du angav. Nå, se hva som skjer når jeg kjører skriptet med flere inngangsfiler.
Det er noe nytt! "$ @" Er en snarvei for "$ 1 $ 2 $ 3 … $ n". Med andre ord er det en fullstendig liste over alle argumenter du angav. Nå, se hva som skjer når jeg kjører skriptet med flere inngangsfiler.
Du kan se hvilke filer som er i mappen min. Jeg kjørte kommandoen med seks argumenter, og hver fil ble lagt til i et zip-arkiv med navnet "archive.zip". Enkelt, ikke sant?
Du kan se hvilke filer som er i mappen min. Jeg kjørte kommandoen med seks argumenter, og hver fil ble lagt til i et zip-arkiv med navnet "archive.zip". Enkelt, ikke sant?

For sløyfer er ganske fantastiske. Nå kan du utføre batchfunksjoner på lister over filer. Du kan for eksempel kopiere alle skriptets argumenter til et zip-arkiv, flytte originaler til en annen mappe, og sikre automatisk kopiere den zip-filen til en ekstern datamaskin. Hvis du konfigurerer nøkkelfiler med SSH, trenger du ikke engang å skrive inn passordet ditt, og du kan til og med fortelle skriptet om å slette zip-filen etter opplasting av det!

Ved hjelp av forløser gjør det enkelt å gjøre en rekke handlinger for alle filer i en katalog. Du kan stable et bredt utvalg av kommandoer sammen og bruke argumenter veldig enkelt til å lage og flytte listen, og dette er bare toppen av isfjellet.

Bash scripters, har du noen forslag? Har du laget et nyttig skript som bruker sløyfer? Vil du dele tankene dine på serien? Legg igjen noen kommentarer og hjelp andre skripting nybegynnere ut!

Anbefalt: