Каково точное значение IFS = $ '\ n'? - PullRequest
113 голосов
/ 09 ноября 2010

Если следующий пример, который устанавливает переменную окружения 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' и я подумал, может ли кто-нибудь дать мне объяснение этому.

Ответы [ 6 ]

151 голосов
/ 09 ноября 2010

Обычно bash не интерпретирует escape-последовательности в строковых литералах. Поэтому, если вы пишете \n или "\n" или '\n', это не перевод строки - это буква n (в первом случае) или обратный слеш, за которым следует буква n (в двух других случаях) .

$'somestring' - это синтаксис для строковых литералов с escape-последовательностями . Так что в отличие от '\n', $'\n' на самом деле является переносом строки.

18 голосов
/ 13 марта 2015

Просто чтобы дать конструкции официальное имя : строки вида $'...' называются ANSI C-цитируемые строки .

То есть, как и в [ANSI] C-строках, escape-последовательности обратной реакции распознаются и расширяются до их буквального эквивалента (полный список поддерживаемых escape-последовательностей см. Ниже).

После этого расширения строки $'...' ведут себя так же, как '...' строки - то есть они обрабатываются как литералы НЕ подлежит [дальнейшему] расширению оболочки .

Например, $'\n' расширяется до буквального символа новой строки - что-то, что является обычным литералом строки bash (будь то '...' или "...") не может сделать. [1]

Еще одна интересная особенность заключается в том, что строки в кавычках ANSI C могут экранировать ' (одинарные кавычки) как \', что, '...' (обычные строки в одинарных кавычках) не могут:

echo $'Honey, I\'m home' # OK; this cannot be done with '...'

Список поддерживаемых escape-последовательностей :

Экранирующие последовательности обратной косой черты, если они есть, декодируются следующим образом:

\ a alert (bell)

\ b backspace

\ e \ E escape-символ (не ANSI C)

\ f подача формы

\ n новая строка

\ r возврат каретки

\ tгоризонтальная табуляция

\ v вертикальная табуляция

\ обратная косая черта

\ 'одинарная кавычка

\ "двойная кавычка

\ nnn восьмая-битный символ, значение которого является восьмеричным значением nnn (от одной до трех цифр)

\ xHH восьмибитный символ, значением которого является шестнадцатеричное значение HH (одна или две шестнадцатеричные цифры)

\uHHHH символ Unicode (ISO / IEC 10646), значением которого является шестнадцатеричное значение HHHH (от одной до четырех шестнадцатеричных цифр)

\ UHHHHHHHH символ Unicode (ISO / IEC 10646), значением которого является шестнадцатеричное значение HHHHHHHH (одиндо восьми шестнадцатеричных цифр)

\ cx контрольного символа x

Расширенный результат заключен в одинарные кавычки, как если бы знак доллара отсутствовал.


[1] Однако вы можете вставлять фактические новые строки в строки "..." и "...";т.е. вы можете определить строки, которые занимают несколько строк.

16 голосов
/ 09 ноября 2010

С http://www.linuxtopia.org/online_books/bash_guide_for_beginners/sect_03_03.html:

Слова в форме "$ 'STRING'" относиться особым образом. Слово расширяется до строки, с заменены символы с обратной косой чертой как указано в стандарте ANSI-C. Escape-последовательности с обратной косой чертой могут быть находится в документации Bash. Найдено

Полагаю, это заставляет сценарий экранировать перевод строки в соответствии со стандартом ANSI-C.

8 голосов
/ 09 апреля 2013

Повторное восстановление IFS по умолчанию - это OLDIFS=$IFS не требуется. Запустите новый IFS в подоболочке, чтобы избежать переопределения стандартного IFS:

ar=(123 321); ( IFS=$'\n'; echo ${ar[*]} )

Кроме того, я не верю, что вы полностью восстановите старый IFS. Вы должны заключить его в двойные кавычки, чтобы избежать разрыва строки, например OLDIFS="$IFS".

2 голосов
/ 11 января 2017

ANSI C-цитируемые строки - ключевой момент. Благодаря @ mklement0.

Вы можете протестировать строки в кавычках ANSI C с помощью команды 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

Вы можете ясно узнать значение по выводам.

0 голосов
/ 09 ноября 2010

Это похоже на получение значения из переменной:

VAR='test'
echo VAR
echo $VAR

отличаются, поэтому знак доллара в основном оценивает содержимое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...