На початку сценарію оболонки 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