Bash                
            Разделение слов
        
        
            
    Поиск…
Синтаксис
- Установите IFS в новую строку: IFS = $ '\ n'
- Установите IFS на nullstring: IFS =
- Установите IFS в / символ: IFS = /
параметры
| параметр | подробности | 
|---|---|
| IFS | Внутренний разделитель полей | 
| -Икс | Команды печати и их аргументы по мере их выполнения (опция Shell) | 
замечания
-  Разделение слов не выполняется во время присвоений, например newvar=$var
-  Разделение слов не выполняется в конструкции [[ ... ]]
- Используйте двойные кавычки для переменных, чтобы предотвратить разделение слов
Разделение с IFS
 Чтобы быть более понятным, давайте создадим скрипт с именем showarg : 
#!/usr/bin/env bash
printf "%d args:" $#
printf " <%s>" "$@"
echo
Теперь посмотрим различия:
$ var="This is an example"
$ showarg $var
4 args: <This> <is> <an> <example>
$varделится на 4 аргумента.IFS- это символы пробела и, следовательно, разбиение слов происходит в пробелах
$ var="This/is/an/example"
$ showarg $var
1 args: <This/is/an/example>
В предыдущем слове расщепление не произошло, потому что символы
IFSне были найдены.
 Теперь давайте установим IFS=/ 
$ IFS=/
$ var="This/is/an/example"
$ showarg $var
4 args: <This> <is> <an> <example>
$varделится на 4 аргумента, а не один аргумент.
Что, когда и почему?
 Когда оболочка выполняет расширение параметра , подмену команды , переменное или арифметическое расширение , он сканирует границы слова в результате. Если какая-либо граница слова найдена, результат разбивается на несколько слов в этой позиции. Граница слова определяется переменной оболочки IFS (Internal Field Separator). Значением по умолчанию для IFS являются пробел, табуляция и новая строка, то есть разделение слов будет происходить на этих трех символах пробела, если это не будет предотвращено явно. 
set -x
var='I am
a
multiline string'
fun() {
    echo "-$1-"
    echo "*$2*"
    echo ".$3."
}
fun $var
 В приведенном выше примере это то, как выполняется функция fun : 
fun I am a multiline string
$varделится на 5 аргументов, будет напечатан толькоI,amиa.
IFS & разбиение слов
Посмотрите, что, когда и почему, если вы не знаете о присоединении IFS к разбиению слов
давайте зададим IFS только символу пробела:
set -x
var='I am
a
multiline string'
IFS=' '
fun() {
    echo "-$1-"
    echo "*$2*"
    echo ".$3."
}
fun $var
 Это расщепление слова будет работать только на пространствах. Функция fun будет выполнена следующим образом: 
fun I 'am
a
multiline' string
$varделится на 3 аргумента.I,am\na\nmultilineиstringбудет напечатана
Давайте установим IFS только для новой строки:
IFS=$'\n'
...
 Теперь fun будет выполнена как: 
fun 'I am' a 'multiline string'
$varделится на 3 аргумента.I am,a,multiline stringбудет напечатана
Давайте посмотрим, что произойдет, если мы установим IFS в nullstring:
IFS=
...
 На этот раз fun будет выполнена следующим образом: 
fun 'I am
a
multiline string'
$varне разделяется, т. е. остается одним аргументом.
Вы можете предотвратить разбиение слов, установив IFS в nullstring
Общий способ предотвращения разделения слов - использовать двойную кавычку:
fun "$var"
 будет предотвращать расщепление слов во всех рассмотренных выше случаях, т. е. функция fun будет выполняться только с одним аргументом. 
Плохие эффекты расщепления слов
$ a='I am a string with spaces'
$ [ $a = $a ] || echo "didn't match"
bash: [: too many arguments
didn't match
[ $a = $a ]интерпретируется как[ I am a string with spaces = I am a string with spaces ].[этоtestкоманда, для которойI am a string with spaces- это не один аргумент, а 6 аргументов!
$ [ $a = something ] || echo "didn't match"
bash: [: too many arguments
didn't match
[ $a = something ]интерпретируется как[ I am a string with spaces = something ]
$ [ $(grep . file) = 'something' ]
bash: [: too many arguments
Команда
grepвозвращает многострочную строку с пробелами, поэтому вы можете просто представить, сколько аргументов существует ...: D
Посмотрите, что, когда и зачем основы.
Полезность расщепления слов
Существуют случаи, когда разбиение слов может быть полезным:
Заполнение массива:
arr=($(grep -o '[0-9]\+' file))
Это заполнит
arrвсеми численными значениями, найденными в файле
Циклическое выделение пробелов:
words='foo bar baz'
for w in $words;do
    echo "W: $w"
done
Выход:
W: foo
W: bar
W: baz
Передача разделенных пробелов параметров, которые не содержат пробелов:
packs='apache2 php php-mbstring php-mysql'
sudo apt-get install $packs
или же
packs='
apache2
php
php-mbstring
php-mysql
'
sudo apt-get install $packs
Это установит пакеты. Если вы удвоите кавычки
$packsто это вызовет ошибку.
Unquoetd
$packsотправляет все имена разделяемых пространств в качестве аргументовapt-get, в то время как цитирование будет отправлять строку$packsкак один аргумент, а затемapt-getпопытается установить пакет с именемapache2 php php-mbstring php-mysql(для первого), который, очевидно, не существует
Посмотрите, что, когда и зачем основы.
Разделение по разделительным изменениям
Мы можем просто выполнить простую замену разделителей из пространства на новую, как показано ниже.
echo $sentence | tr " " "\n"
 Он разделит значение sentence переменной и покажет его по строке соответственно.