Bash
Orddelning
Sök…
Syntax
- Ställ IFS till ny linje: IFS = $ '\ n'
- Ställ IFS till nollsträng: IFS =
- Ställ IFS till / karaktär: IFS = /
parametrar
| Parameter | detaljer |
|---|---|
| IFS | Intern fältavskiljare |
| -x | Skriv ut kommandon och deras argument när de körs (Shell-alternativ) |
Anmärkningar
- Orddelning utförs inte under uppdrag t.ex.
newvar=$var - Orddelning utförs inte i
[[ ... ]]-konstruktionen - Använd dubbla citat på variabler för att förhindra att orddelning sker
Dela med IFS
För att vara mer tydlig, låt oss skapa ett skript med namnet showarg :
#!/usr/bin/env bash
printf "%d args:" $#
printf " <%s>" "$@"
echo
Låt oss nu se skillnaderna:
$ var="This is an example"
$ showarg $var
4 args: <This> <is> <an> <example>
$vardelas upp i 4 args.IFSär vita mellanslagstecken och således skedde orddelning i mellanslag
$ var="This/is/an/example"
$ showarg $var
1 args: <This/is/an/example>
I ovanstående orddelning inträffade inte eftersom
IFStecken inte hittades.
Låt oss nu ställa in IFS=/
$ IFS=/
$ var="This/is/an/example"
$ showarg $var
4 args: <This> <is> <an> <example>
$vardelar in sig i fyra argument, inte ett enda argument.
Vad, när och varför?
När skalet utför parameterutvidgning , kommandosubstitution , variabel eller aritmetisk expansion , söker det efter ordgränser i resultatet. Om någon ordgräns hittas, delas resultatet upp i flera ord i den positionen. Ordsgränsen definieras av en skalvariabel IFS (Internal Field Separator). Standardvärdet för IFS är utrymme, flik och ny linje, dvs orddelning kommer att inträffa på dessa tre vitrumstecken om de inte förhindras uttryckligen.
set -x
var='I am
a
multiline string'
fun() {
echo "-$1-"
echo "*$2*"
echo ".$3."
}
fun $var
I exemplet ovan är detta hur fun körs:
fun I am a multiline string
$vardelas upp i 5 args, baraI,amochakommer att skrivas ut.
IFS & orddelning
Se vad, när och varför om du inte vet om IFS-anslutningen till orddelning
låt oss ställa in IFS till mellanslagstecken:
set -x
var='I am
a
multiline string'
IFS=' '
fun() {
echo "-$1-"
echo "*$2*"
echo ".$3."
}
fun $var
Denna tidsorddelning fungerar bara på mellanslag. Den fun funktionen kommer att köras så här:
fun I 'am
a
multiline' string
$vardelas upp i 3 args.I,am\na\nmultilineochstringkommer att skrivas ut
Låt oss ställa IFS till ny linje:
IFS=$'\n'
...
Nu kommer det fun att utföras som:
fun 'I am' a 'multiline string'
$vardelas upp i 3 args.I am,a,multiline stringkommer att skrivas ut
Låt oss se vad som händer om vi ställer IFS till nullsträng:
IFS=
...
Den här gången utförs det fun :
fun 'I am
a
multiline string'
$varär inte delad, dvs det förblev en enda arg.
Du kan förhindra orddelning genom att ställa IFS till nollsträng
Ett generellt sätt att förhindra orddelning är att använda dubbelcitationstecken:
fun "$var"
kommer att förhindra att orddelning sker i alla fall som diskuterats ovan, dvs fun kommer att köras med bara ett argument.
Dåliga effekter av orddelning
$ a='I am a string with spaces'
$ [ $a = $a ] || echo "didn't match"
bash: [: too many arguments
didn't match
[ $a = $a ]tolkades som[ I am a string with spaces = I am a string with spaces ].[ärtestför vilketI am a string with spacesär inte ett enda argument, snarare är det 6 argument !!
$ [ $a = something ] || echo "didn't match"
bash: [: too many arguments
didn't match
[ $a = something ]tolkades som[ I am a string with spaces = something ]
$ [ $(grep . file) = 'something' ]
bash: [: too many arguments
grepkommandot returnerar en multiline sträng med mellanslag, så du kan bara tänka dig hur många argument som finns ...: D
Se vad, när och varför för grunderna.
Användbarhet vid orddelning
Det finns några fall där orddelning kan vara användbar:
Fylla upp matris:
arr=($(grep -o '[0-9]\+' file))
Detta kommer att fylla
arrmed alla numeriska värden som finns i filen
Looping genom rymdseparerade ord:
words='foo bar baz'
for w in $words;do
echo "W: $w"
done
Produktion:
W: foo
W: bar
W: baz
Passera utrymme separerade parametrar som inte innehåller vita mellanslag:
packs='apache2 php php-mbstring php-mysql'
sudo apt-get install $packs
eller
packs='
apache2
php
php-mbstring
php-mysql
'
sudo apt-get install $packs
Detta kommer att installera paketen. Om du dubblar offert på
$packskommer det att kasta ett fel.
Unquoetd
$packsskickar alla utrymme separerade paketnamn som argument tillapt-get, medan de citerar kommer det att skicka$packssträngen som ett enda argument och sedan kommerapt-getatt försöka installera ett paket med namnetapache2 php php-mbstring php-mysql(för den första) som uppenbarligen inte finns
Se vad, när och varför för grunderna.
Delning med separatorändringar
Vi kan bara göra en enkel byte av separatorer från rymd till ny linje, enligt följande exempel.
echo $sentence | tr " " "\n"
Den delar upp värdet på den variabla sentence och visar den rad för rad respektive.