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>

$var delas 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 IFS tecken inte hittades.

Låt oss nu ställa in IFS=/

$ IFS=/
$ var="This/is/an/example"
$ showarg $var
4 args: <This> <is> <an> <example>

$var delar 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

$var delas upp i 5 args, bara I , am och a kommer 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

$var delas upp i 3 args. I , am\na\nmultiline och string kommer 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'

$var delas upp i 3 args. I am , a , multiline string kommer 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 ] . [ är test för vilket I 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

grep kommandot 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 arr med 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å $packs kommer det att kasta ett fel.

Unquoetd $packs skickar alla utrymme separerade paketnamn som argument till apt-get , medan de citerar kommer det att skicka $packs strängen som ett enda argument och sedan kommer apt-get att försöka installera ett paket med namnet apache2 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.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow