На початку сценарію оболонки bash є наступний рядок:
IFS=$'\n'
Яке значення стоїть за цією колекцією символів?
IFS=$'\n'
є bashism (+ інші оболонки, використовувати ANSI-C Цитування , для обходу см stackoverflow.com/questions/10748703 / ...
На початку сценарію оболонки bash є наступний рядок:
IFS=$'\n'
Яке значення стоїть за цією колекцією символів?
IFS=$'\n'
є bashism (+ інші оболонки, використовувати ANSI-C Цитування , для обходу см stackoverflow.com/questions/10748703 / ...
Відповіді:
IFS
означає "внутрішній роздільник поля". Вона використовується шкаралупою для визначення способів розбиття слів, тобто розпізнавання меж слова.
Спробуйте це в оболонці, як bash (інші оболонки можуть поводитися з цим по-різному, наприклад zsh):
mystring="foo:bar baz rab"
for word in $mystring; do
echo "Word: $word"
done
Значення за замовчуванням для IFS
складається з символів пробілу (якщо бути точним: пробіл, вкладка та новий рядок). Кожен символ може бути межею слова. Отже, за замовчуванням значення IFS
циклу буде надруковано вище:
Word: foo:bar
Word: baz
Word: rab
Іншими словами, оболонка вважає, що пробіл - це межа слова.
Тепер спробуйте встановити IFS=:
перед виконанням циклу. Цього разу результат:
Word: foo
Word: bar baz rab
Тепер оболонка також розпадається mystring
на слова - але тепер вона розглядає лише двокрапку як границю слова.
Перший символ IFS
спеціального: Він використовується для розмежування слів у висновку під час використання спеціальної $*
змінної (приклад, взятий із Посібника з розширеного сценарію вдосконаленого тексту , де ви також можете знайти додаткову інформацію про спеціальні змінні на зразок цієї):
$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z
Порівняти з:
$ bash -c 'set w x y z; IFS="-:;"; echo "$*"'
w-x-y-z
Зверніть увагу , що в обох прикладах, оболонка буде по- , як і раніше ставитися все символи :
, -
а ;
також кордону слів. Єдине, що змінюється, - це поведінка $*
.
Ще одна важлива річ, яку потрібно знати, як трактується так званий "пробіл IFS" . По суті, як тільки IFS
символи пробілів містять пробіли, провідні та кінцеві пробіли позбавляються від рядка для розбиття перед його обробкою, а послідовність послідовних символів пробілу також обмежує поля. Однак це стосується лише тих символів пробілу, які фактично присутні у IFS
.
Наприклад, давайте подивимось на рядок "a:b:: c d "
(пробіл та два пробіли між c
та d
).
IFS=:
він буде розділений на чотири поля: "a"
, "b"
, ""
(порожній рядок) і " c d "
(знову ж , два простору між c
і d
). Зверніть увагу на провідну та кінцеву пробіли в останньому полі.IFS=' :'
, вона буде розділена на п'ять полів: "a"
, "b"
, ""
(порожній рядок), "c"
і "d"
. Ніде немає провідних і задніх пробілів.Зверніть увагу, як кілька послідовних символів пробілів розмежовують два поля у другому прикладі, тоді як декілька послідовних кольорів - це не символи (оскільки вони не є символами пробілу).
Що ж стосується IFS=$'\n'
, тобто ksh93
синтаксис також підтримується bash
, zsh
, mksh
і FreeBSD sh
(з варіаціями між усіма оболонками). Цитування баш-сторінки:
Слова форми $ 'string "обробляються спеціально. Слово розширюється на "рядок", при цьому символи, що ухиляються від косої риски, замінюються, як визначено стандартом ANSI C.
\n
є послідовністю відходу для нового рядка, тому в IFS
кінцевому підсумку встановлюється один символ нового рядка.
bash
написання сценаріїв чи будь-що інше. В основному, інформації, доступної за такими посиланнями, бракує важливих способів. У будь-якому випадку, таким чином, не вистачає двох найважливіших моментів, що стосуються розщеплення оболонок - глобулювання та пробіл IFS.
unset IFS
робить оболонка поводиться зовсім інакше , ніж IFS=
. Також перший байт в IFS також є спеціальним "${named_array[*]}"
, але не має значення, коли розширення не
$IFS
є однією з двох головних речей, що виконуються при розширенні нецитованої змінної в контексті списку (це split
частина split+glob
оператора). Інший - глобус. Під час використання розбивки на роботу, як правило, потрібно видалити, set -f
щоб вимкнути glob
деталь.
$IFS
також використовується read
вбудованою командою
Всередині одинарних цитат, що знаходяться в доларі, деякі символи оцінюються спеціально. Наприклад, \n
переведений на новий рядок.
Отже, саме цей рядок присвоює нову рядок змінній IFS. IFS, у свою чергу, є спеціальною змінною в bash: Internal Field Separator. Як man bash
кажуть, це
використовується для розбиття слів після розширення та для розділення рядків на слова за допомогою
read
вбудованої команди. Значенням за замовчуванням є<space><tab><newline>
.
dollared single quotes
що відрізняється від простих одиничних цитат.
Якщо коротко, IFS=$'\n'
призначте нову рядок \n
змінній IFS
.
$'string'
Конструкція - це механізм цитування, який використовується для декодування ANSI C, як послідовності втечі Цей синтаксис походить від ksh93
, і був портативним сучасної оболонці , як bash
, zsh
, pdksh
, busybox sh
.
Цей синтаксис не визначений POSIX, але був прийнятий для випуску 7 SUS .
Я вважаю за краще пояснити $IFS
через приклад:
Suppsoe, який ви хочете cp, mv або інший файл, що обробляє файл, IFS порожній за допомогою defualt, коли у ваших файлів є мета-діаграма або пробіл, наприклад:
Linux Administration.pdf
або Free Software Fundation.ogg
, звичайно, у вас буде проблема, тому що: Linux вважає, що окремий парам і Administartion розглядають окремий парам. Отже, баш має built-in variable
, тоді ви можете ініціалізуватись IFS==$(echo -en "\n\b")
, Потім баш відкинути будь-які метапотоки та пробіл між назвою файлу, наприклад:
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
mymusicdir=~/test/dd
find $mymusicdir -name "*" -execdir rename 's/ /_/g' "{}" +
IFS=$SAVEIFS