Zoeken…


Syntaxis

  • Zet IFS op newline: IFS = $ '\ n'
  • Zet IFS op nullstring: IFS =
  • Zet IFS op / character: IFS = /

parameters

Parameter Details
IFS Intern veldscheidingsteken
-X Opdrachten en hun argumenten afdrukken terwijl ze worden uitgevoerd (optie Shell)

Opmerkingen

  • newvar=$var wordt niet uitgevoerd tijdens opdrachten, bijvoorbeeld newvar=$var
  • Woordsplitsing wordt niet uitgevoerd in het [[ ... ]] construct
  • Gebruik dubbele aanhalingstekens op variabelen om splitsing van woorden te voorkomen

Splitsen met IFS

Laten we voor de duidelijkheid een script maken met de naam showarg :

#!/usr/bin/env bash
printf "%d args:" $#
printf " <%s>" "$@"
echo

Laten we nu de verschillen bekijken:

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

$var is opgesplitst in 4 args. IFS is witruimte-tekens en er vond dus splitsing van woorden plaats in spaties

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

In het bovenstaande vond geen woordsplitsing plaats omdat de IFS tekens niet werden gevonden.

Laten we nu IFS=/

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

De $var splitst zich in 4 argumenten, geen enkel argument.

Wat, wanneer en waarom?

Wanneer de shell parameteruitbreiding , opdrachtvervanging , variabele of rekenkundige uitbreiding uitvoert, scant deze op woordgrenzen in het resultaat. Als een woordgrens wordt gevonden, wordt het resultaat op die positie in meerdere woorden gesplitst. De woordgrens wordt gedefinieerd door een shell-variabele IFS (Internal Field Separator). De standaardwaarde voor IFS zijn spatie, tab en nieuwe regel, dat wil zeggen dat woordsplitsing op deze drie witruimte-tekens voorkomt als dit niet expliciet wordt voorkomen.

set -x
var='I am
a
multiline string'
fun() {
    echo "-$1-"
    echo "*$2*"
    echo ".$3."
}
fun $var

In het bovenstaande voorbeeld is dit hoe de fun functie wordt uitgevoerd:

fun I am a multiline string

$var is verdeeld in 5 args, alleen I , am en a zal worden afgedrukt.

IFS & woordsplitsing

Kijk wat, wanneer en waarom als u niet weet hoe IFS is aangesloten bij woordsplitsing

laten we het IFS alleen op spatie plaatsen:

set -x
var='I am
a
multiline string'
IFS=' '
fun() {
    echo "-$1-"
    echo "*$2*"
    echo ".$3."
}
fun $var

Deze tijd splitsen van woorden werkt alleen op spaties. De fun functie wordt als volgt uitgevoerd:

fun I 'am
a
multiline' string

$var is opgesplitst in 3 args. I , am\na\nmultiline en string worden afgedrukt

Laten we de IFS alleen instellen op nieuwe regel:

IFS=$'\n'
...

Nu wordt het fun uitgevoerd als:

fun 'I am' a 'multiline string'

$var is opgesplitst in 3 args. I am a multiline string wordt afgedrukt

Laten we eens kijken wat er gebeurt als we IFS instellen op nullstring:

IFS=
...

Deze keer wordt het fun als volgt uitgevoerd:

fun 'I am
a
multiline string'

$var is niet gesplitst, dwz het bleef een enkele arg.

U kunt het splitsen van woorden voorkomen door de IFS in te stellen op nullstring

Een algemene manier om het splitsen van woorden te voorkomen, is door dubbele aanhalingstekens te gebruiken:

fun "$var"

voorkomt het splitsen van woorden in alle hierboven besproken gevallen, dwz dat de fun functie met slechts één argument wordt uitgevoerd.

Slechte effecten van woordsplitsing

$ a='I am a string with spaces'
$ [ $a = $a ] || echo "didn't match"
bash: [: too many arguments
didn't match

[ $a = $a ] werd geïnterpreteerd als [ I am a string with spaces = I am a string with spaces ] . [ is het test waarvoor I am a string with spaces ben, geen enkel argument, het zijn eerder 6 argumenten !!

$ [ $a = something ] || echo "didn't match"
bash: [: too many arguments
didn't match

[ $a = something ] werd geïnterpreteerd als [ I am a string with spaces = something ]

$ [ $(grep . file) = 'something' ]
bash: [: too many arguments

De opdracht grep retourneert een tekenreeks met meerdere regels met spaties, dus u kunt zich gewoon voorstellen hoeveel argumenten er zijn ...: D

Zie wat, wanneer en waarom voor de basis.

Nut van woordsplitsing

Er zijn enkele gevallen waarin woordsplitsing nuttig kan zijn:

Array vullen:

arr=($(grep -o '[0-9]\+' file))

Hiermee vult u arr met alle numerieke waarden in het bestand

Door de spatie gescheiden woorden doorlussen:

words='foo bar baz'
for w in $words;do
    echo "W: $w"
done

Output:

W: foo
W: bar
W: baz

Doorgegeven spaties gescheiden parameters die geen spaties bevatten:

packs='apache2 php php-mbstring php-mysql'
sudo apt-get install $packs

of

packs='
apache2
php
php-mbstring
php-mysql
'
sudo apt-get install $packs

Hiermee worden de pakketten geïnstalleerd. Als u de $packs dubbel citeert $packs geeft dit een foutmelding.

Unquoetd $packs verzendt alle door de ruimte gescheiden pakketnamen als argumenten voor apt-get , terwijl het citaat de $packs string als een enkel argument verzendt en dan probeert apt-get een pakket met de naam apache2 php php-mbstring php-mysql (voor de eerste) die duidelijk niet bestaat

Zie wat, wanneer en waarom voor de basis.

Splitsen door scheidingstekens

We kunnen eenvoudig de scheidingstekens van ruimte naar nieuwe regel vervangen, zoals in het volgende voorbeeld.

echo $sentence | tr " " "\n"

Het splitst de waarde van de variabele sentence en geeft deze respectievelijk regel voor regel weer.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow