Bash skriptu es gribētu sadalīt rindu gabalos un saglabāt tos masīvā.
Rinda:
Paris, France, Europe
Es gribētu, lai tie būtu masīvā, piemēram, šādā veidā:
array[0] = Paris
array[1] = France
array[2] = Europe
Es gribētu izmantot vienkāršu kodu, komandas ātrumam nav nozīmes. Kā es varu to izdarīt?
IFS=', ' read -r -a array <<< "$string"
Ņemiet vērā, ka $IFS
rakstzīmes tiek uzskatītas par atdalītājiem atsevišķi, tāpēc šajā gadījumā laukus var atdalīt ar _atkarībā ar komatu vai atstarpi, nevis ar šo divu rakstzīmju secību. Interesanti, ka tukši lauki netiek izveidoti, ja ievadē parādās komats un atstarpe, jo atstarpi apstrādā īpaši.
Lai piekļūtu atsevišķam elementam:
echo "${array[0]}"
Elementu iterācija:
for element in "${array[@]}"
do
echo "$element"
done
Lai iegūtu gan indeksu, gan vērtību:
for index in "${!array[@]}"
do
echo "$index ${array[index]}"
done
Pēdējais piemērs ir noderīgs, jo Bash masīvi ir reti. Citiem vārdiem sakot, jūs varat izdzēst elementu vai pievienot elementu, un tad indeksi nav savienoti.
unset "array[1]"
array[42]=Earth
Lai iegūtu elementu skaitu masīvā:
echo "${#array[@]}"
Kā minēts iepriekš, masīvi var būt reti, tāpēc nevajadzētu izmantot garumu, lai iegūtu pēdējo elementu. Lūk, kā to var izdarīt Bash 4.2 un jaunākās versijās:
echo "${array[-1]}"
jebkurā Bash versijā (sākot no 2.05b):
echo "${array[@]: -1:1}"
Lielāki negatīvie nobīdi atlasa tālāk no masīva beigām. Pievērsiet uzmanību atstarpei pirms mīnusa zīmes vecākajā formā. Tā ir obligāta.
Šeit ir veids, kā to izdarīt bez IFS iestatīšanas:
string="1:2:3:4:5"
set -f # avoid globbing (expansion of *).
array=(${string//:/ })
for i in "${!array[@]}"
do
echo "$i=>${array[i]}"
done
Ideja ir izmantot virknes aizvietošanu:
${string//substring/replacement}
lai aizstātu visus virknes $substring sakritības gadījumus ar baltu atstarpi un pēc tam aizstāto virkni izmantotu masīva inicializēšanai:
(element1 element2 ... elementN)
Piezīme: šajā atbildē izmantots split+glob operators. Tādējādi, lai novērstu dažu rakstzīmju (piemēram, *
) izvēršanu, šajā skripta gadījumā ir labi apturēt globbēšanu.
Dažreiz man gadījās, ka akceptētajā atbildē aprakstītā metode nedarbojās, it īpaši, ja atdalītājs ir karriage return.
Šādos gadījumos es to atrisināju šādi:
string='first line
second line
third line'
oldIFS="$IFS"
IFS='
'
IFS=${IFS:0:1} # this is useful to format your code with tabs
lines=( $string )
IFS="$oldIFS"
for line in "${lines[@]}"
do
echo "--> $line"
done