Bash
Woord splitsen
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, bijvoorbeeldnewvar=$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, alleenI
,am
ena
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
enstring
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 hettest
waarvoorI 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 voorapt-get
, terwijl het citaat de$packs
string als een enkel argument verzendt en dan probeertapt-get
een pakket met de naamapache2 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.