Каково точное значение IFS = $'\n'?
Если следующий пример, который устанавливает переменную среды IFS
символу строки...
IFS=$'\n'
- Что означает знак доллар
точно
- Что он делает в этом конкретном
случай?
- Где я могу узнать больше об этом конкретном использовании (Google не разрешает специальные символы при поиске, и я не знаю, что искать в противном случае)?
Я знаю, что такое переменная среды IFS
, и какой символ \n
(строка), но почему бы просто не использовать следующую форму:
IFS="\n"
(который не работает)?
Например, если я хочу перебирать каждую строку файла и хочу использовать цикл for, я мог бы сделать это:
for line in (< /path/to/file); do
echo "Line: $line"
done
Однако это не будет работать правильно, если только IFS
не установлен на символ линии. Чтобы заставить его работать, я должен был бы сделать это:
OLDIFS=$IFS
IFS=$'\n'
for line in (< /path/to/file); do
echo "Line: $line"
done
IFS=$OLDIFS
Примечание: Мне не нужен другой способ сделать то же самое, я знаю много других... Мне только интересно, что $'\n'
и задавался вопросом, может ли кто-нибудь дать мне объяснение на нем.
Ответы
Ответ 1
Обычно bash
не интерпретирует escape-последовательности в строковых литералах. Поэтому, если вы пишете \n
или "\n"
или '\n'
, это не строка - это буква n
(в первом случае) или обратная косая черта, сопровождаемая буквой n
(в двух других случаях).
$'somestring'
- синтаксис для строковых литералов с escape-последовательностями. Таким образом, в отличие от '\n'
, $'\n'
на самом деле является строкой.
Ответ 2
Просто, чтобы дать конструктору его официальное название : строки формы $'...'
называются ANSI C-quoted строки.
То есть, как в строках [ANSI] C, escape-последовательности обратного вызова распознаются и расширяются до их эквивалентного литерала (см. ниже полный список поддерживаемых управляющих последовательностей).
После этого расширения строки $'...'
ведут себя так же, как '...'
строки, т.е. они рассматриваются как литералы, не подлежащие никаким [дальнейшим] расширениям оболочки.
Например, $'\n'
расширяется до символа символа новой строки, который является чем-то регулярным bash строковым литералом (без '...'
или "..."
). [1]
Еще одна интересная особенность заключается в том, что строки ANSI C могут выходить '
(одинарные кавычки) как \'
, что '...'
(обычные строки с одной кавычкой) не может:
echo $'Honey, I\'m home' # OK; this cannot be done with '...'
Список поддерживаемых escape-последовательностей:
Управляющие последовательности обратного слэша, если они есть, декодируются следующим образом:
\ а alert (звонок)
\ б Забой
\ е \ E escape-символ (не ANSI C)
\ е form feed
\ п новая строка
\ г возврат каретки
\ т горизонтальная вкладка
\ v вертикальная вкладка
\ обратной косой черты
\ "одиночная кавычка
\" двойная кавычка
\nNN восьмибитовый символ, значением которого является восьмеричное значение nnn (от одной до трех цифр)
\ xHH восьмибитовый символ, значение которого представляет собой шестнадцатеричное значение HH (одна или две шестнадцатеричные цифры)
\ Uhhhh символ Unicode (ISO/IEC 10646), значение которого представляет собой шестнадцатеричное значение HHHH (от одной до четырех шестнадцатеричных цифр)
\ UHHHHHHHH символ Unicode (ISO/IEC 10646), значение которого представляет собой шестнадцатеричное значение HHHHHHHH (от одной до восьми шестнадцатеричных цифр)
\ сх символ control-x
Расширенный результат одинарный, как будто знак доллара не присутствовал.
[1] Вы можете, однако, внедрить фактические строки в строки "..." и "..."; т.е. вы можете определить строки, которые охватывают несколько строк.
Ответ 3
Из http://www.linuxtopia.org/online_books/bash_guide_for_beginners/sect_03_03.html:
Слова в форме "$ STRING" обработанный особым образом. Слово расширяется до строки, с заменены символы с обратной косой чертой как указано в стандарте ANSI-C. Последующие последовательности обратной косой черты могут быть найденный в Bash documentation.found
Я предполагаю, что он заставил script выйти из строки в соответствующий стандарт ANSI-C.
Ответ 4
Повторное восстановление IFS по умолчанию - это не требуется OLDIFS=$IFS
. Запустите новый IFS в подоболочке, чтобы избежать переопределения IFS по умолчанию:
ar=(123 321); ( IFS=$'\n'; echo ${ar[*]} )
Кроме того, я действительно не верю, что вы полностью восстановите старый IFS. Вы должны удвоить его, чтобы избежать разрыва строки, например OLDIFS="$IFS"
.
Ответ 5
Строки с котировками ANSI - ключевой момент. Благодаря @mklement0.
Вы можете протестировать строки с котировкой ANSI с командой od.
echo -n $'\n' | od -c
echo -n '\n' | od -c
echo -n $"\n" | od -c
echo -n "\n" | od -c
Выходы:
0000000 \n
0000001
0000000 \ n
0000002
0000000 \ n
0000002
0000000 \ n
0000002
Вы можете четко понимать значение вывода.
Ответ 6
Это похоже на извлечение значения из переменной:
VAR='test'
echo VAR
echo $VAR
разные, поэтому знак доллара в основном оценивает содержимое.