Bash mapfile inbyggt kommando



mapfile-kommando

Unix-liknande operativsystem, kartfil är ett inbyggt kommando för Våldsamt slag skal. Det läser rader från standardingång till ett indexerat array variabel .

Dricks



Mer information om bash-variabler finns i arrays in bash .

Syntax

  mapfile  [  -n   count  ] [  -O   origin  ] [  -s   count  ] [  -t  ] [  -u   fd  ] [  -C   callback  [  -c   quantum  ]] [  array  ]

alternativ

De kartfil Inbyggt kommando tar följande alternativ:

-n räkna Läs högst räkna rader. Om räkna är noll, alla tillgängliga rader kopieras.
-ELLER ursprung Börja skriva rader för att matrisera array vid indexnummer ursprung . Standardvärdet är noll.
-s räkna Kasta den första räkna innan du skriver till array .
-t Om någon rad slutar i en ny linje, ta bort den.
-u fd Läs rader från filbeskrivaren fd snarare än standardinmatning.
-C ring tillbaka Utföra / utvärdera en funktion / uttryck, ring tillbaka , varje gång kvant rader läses. Standardvärdet för kvant är 1 , om inte annat anges med -c .
-c kvant Ange antalet rader, kvant , efter vilken funktion / uttryck ring tillbaka ska köras / utvärderas om det anges med -C .
array Namnet på arrayvariabeln där rader ska skrivas. Om array utelämnas, är standardvariabeln MAPFIL är målet.

Anteckningar

Kommandonamnet läsarray kan användas som ett alias för kommandonamnet kartfil , utan skillnad i funktion.

infoga automatiskt datum i word

Om -u alternativet är specificerat, kartfil läser från filbeskrivare fd istället för standardingång.

Om array är inte specificerat är standardvariabeln MAPFIL används som målmatrisvariabel.

De kartfil kommandot är inte särskilt bärbart. Det vill säga om du vill säkerställa din manus kan köras på ett brett utbud av system rekommenderas det inte att använda kartfil . Det tillhandahålls främst som en bekvämlighet. Samma funktionalitet kan uppnås med hjälp av a läsa loop, men i allmänhet kartfil fungerar snabbare.

Utgångsstatus

De kartfil kommandot återgår 0 för framgång, eller 1 om något går fel, t.ex. tillhandahålls ett ogiltigt alternativ, eller målvariabeln är skrivskyddad eller inte en matris.

Exempel

De kartfil kommandot läser inmatning rad för rad och sätter varje rad i en matrisvariabel. Låt oss förse den med flera ingångsrader.

Vi kan använda tryckf att göra detta. Det är ett enkelt sätt att skriva ut text med nya rader .

I vår tryckf formatsträng , vi kan inkludera ' n '(till backslash omedelbart följt av gemener n ) för att skapa en ny rad. (' n 'är en metatecken, en sekvens av tecken som representerar ett annat tecken som inte kan skrivas bokstavligen , till exempel Enter-tangenten. För en fullständig lista över bash-metatecken, se citerar i bash .)

Detta tryckf kommandot skriver ut tre rader text:

printf 'Line 1
Line 2
Line 3
'
 Line 1 Line 2 Line 3

Vi vill använda kartfil att sätta var och en av dessa rader i sitt eget element i en matris.

Som standard kartfil läser från standardinmatning, så du kan bli frestad att pipa utdata från tryckf till kartfil så här:

printf 'Line 1
Line 2
Line 3
' | mapfile

Du förväntar dig standardmatrisvariabeln MAPFIL för att innehålla värdena från dessa rader. Men om du kontrollerar värdet på MAPFIL :

echo '${MAPFILE[@]}'
  [a blank line]  

Variabeln är tom. Varför?

Varje kommando i en pipeline körs i en subshell - en instans av bash, körs som en underprocess. Varje subshell har sin egen miljö och sitt eget lexikala omfång - variablerna som utgör miljön för varje subshell i rörledningen överförs inte till andra. Med andra ord, det finns inga miljömässiga biverkningar som delas från en del av en rörledning till en annan. I vårt exempel ovan, kartfil fungerar korrekt och ställer in värdena för MAPFIL , men när kommandot subshell avslutas, variabeln MAPFIL försvinner.

Du kan se detta om du ekar värdet på MAPFILE inuti en subshell som också innehåller kartfil kommando genom att stänga båda inom parentes:

printf 'Line 1
Line 2
Line 3
' | ( mapfile; echo '${MAPFILE[@]}' )
 Line 1 Line 2 Line 3

I ovanstående kommando, kastade ut skriver ut alla element i arrayvariabeln MAPFIL , åtskilda av ett mellanslag. Utrymmet visas i början av raderna 2 och 3 på grund av de nya raderna i våra data. Vår uttryckliga subshell, uttryckt med parenteser, bevarar värdet av MAPFIL tillräckligt länge för att vi ska kunna se värdena.

Vi kan fixa radbrytningarna genom att ta bort dem med -t :

printf 'Line 1
Line 2
Line 3
' | ( mapfile -t; echo '${MAPFILE[@]}' )
Line 1 Line 2 Line 3

(Vi kan sätta tillbaka linjen i vår produktion om vi använder tryckf - det gör vi i efterföljande exempel.)

Så, kartfil fungerar, men arrayvariabeln är inte tillgänglig för det överordnade skalet. Normalt vill du dock ha MAPFIL variabel för att bestå för efterföljande kommandon. Du kan åstadkomma det med processersättning.

Använda mapfil med processersättning

Med processersättning , kan vi omdirigera utdata till kartfil utan att använda en rörledning.

mapfile -t <<(printf 'Line 1
Line 2
Line 3')

Låt oss titta på de enskilda delarna av detta kommando:

mapfile -t Mapfile tar inmatning från standardinmatning och tar bort nya rader ( -t ) från slutet av varje rad. Detta är (vanligtvis) vad du vill ha: endast radens text lagras i ditt arrayelement och den nya linjetecknet kasseras.
< Den första < är en omdirigeringstecken. Den förväntar sig att följas av ett filnamn eller en beskrivning av filen. Innehållet i den filen omdirigeras till standardinmatningen för föregående kommando.
<( ... ) Dessa tecken indikerar processersättning, som returnerar en filbeskrivare. Kommandona inom parentes körs och deras utdata tilldelas denna filbeskrivare. I vilket bash-kommando som helst kan du använda processersättning som ett filnamn.

När du kör hela kommandot, kartfil läser tyst våra tre textrader och placerar varje rad i enskilda element i standardmatrisvariabeln, MAPFIL .

Vi kan verifiera detta med tryckf för att skriva ut elementen i matrisen.

printf '%s' '${MAPFILE[@]}'

Det första argumentet, '% s' är strängen printf-format. Det andra argumentet, '$ {MAPFILE [@]}' , expanderas med bash. Alla element (' @ ') av array MAPFIL utvidgas till enskilda argument. (För mer information, se: Hänvisar till arrayelement i bash .)

vad är mitt nätverkskort
Line 1Line 2Line 3

Som du kan se skrivs våra tre textrader ut bredvid varandra. Det beror på att vi tog bort de nya linjerna med -t och tryckf matar inte ut nya rader som standard.

För att specificera det tryckf skriva ut en ny linje efter varje rad, använd n i formatsträngen:

printf '%s
' '${MAPFILE[@]}'
Line 1 Line 2 Line 3

För att komma åt enskilda element i matrisen, ersätt @ med ett indexnummer. Numreringen är nollbaserad, så 0 indexerar det första elementet, 1 indexerar den andra, etc:

printf '%s
' '${MAPFILE[0]}'
Line 1
printf '%s
' '${MAPFILE[2]}'
Line 3

läsa - Läs en rad, dela upp den i ord och tilldela varje ord till en variabel.