Символ конца файла linux

Символ конца файла linux

Некоторые символы имеют для редактора особое значение. К ним относятся: «.», «\», «$», «*», «[«, «]», «^», «&». Эти символы обычно называются метасимволами.

6.16.1. Метасимвол . (точка)

В зависимости от контекста символ «.» имеет несколько значений. lin В левой части команды подстановки и при поиске с помощью конструкции «/. /» символ «.» означает любой одиночный символ. Таким образом, в результате поиска будут найдены строки текста, содержащие символы «x» и «y», между которыми находится любой символ, например:

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

Примеры. замена символа «a» на символ «,» в строке, следующей за текущей. Символ «.», записанный в правой части команды замены «s», не имеет специального значения; замена символа «,» на символ «.» в строках с 1-й по 5-ю включительно.

Команда : иллюстрирует все значения символа «.». Первая «.» в команде — это номер текущей строки, вторая «.» это метасимвол, который соответствует любому одному символу данной строки, третья «.» — это настоящая точка в команде замены.

Такая команда, примененная, например к строке: дает результат:

6.16.2. Метасимвол \ (обратная дробная черта)

Обратная дробная черта (или обратный слэш) отменяет специальное значение, которое может иметь следующий за ней символ, в частности, «\.» означает точку, а не «любой символ». Примеры. замена символа «.» на символ «?»; поиск строк, содержащих «.pp»; поиск символа «\»; поиск символа «/»; удаление в текущей строке последовательности символов «.».

Для разделения полей в команде «s» может использоваться любой символ, а не только дробная черта (однако для контекстного поиска требуется использовать дробную черту). Например, если строка уже содержит много символов дробной черты, как в строке: то можно использовать в качестве разделителей символ «:» (двоеточие). Удалить все символы дробной черты можно с помощью команды:

Если для стирания символов и удаления строк используются клавиши «#» и «@», их нужно вводить в виде «\#» и «\@» (это относится не только к работе с ed).

Если текст вводится с помощью одной из команд: «a», «i» или «c», то символ обратной дробной черты не является специальным, и требуется нажимать эту клавишу только один раз для каждой обратной дробной черты.

6.16.3. Метасимвол $ (денежный знак)

В зависимости от того, как используется знак денежной единицы ($), он может обозначать конец файла или конец строки. Когда указывается диапазон (от строки 1 до строки $), совершенно ясно, что речь идет о конце файла. «1, $p» вызовет распечатку всего файла. Но запись «s/$/./p» указывает, что точка будет помещена в конце текущей строки.

В команде: первый символ «$» означает последнюю строку файла, второй означает конец этой строки, а третий действительно является символом денежной единицы, который добавляется к указанной строке.

6.16.4. Метасимвол ^ (отрицание)

Метасимвол «^» применяется так же, как метасимвол «$», за исключением того, что он указывает начало строки, а не конец.

Примеры. поиск строки, начинающейся со слова «время»; поместить пробел в начало текущей строки.

Метасимволы можно объединять. Например, для того, чтобы найти строку, содержащую только символы «pp» можно использовать команду: /^.pp$/

6.16.5. Метасимвол * (звездочка)

Метасимвол «*» означает, что символ, за которым он следует, может повторяться произвольное число раз.

Если в тексте имеется большое количество пробелов, их можно сжать, например: В результате выполнения команды: получим:

Если скомбинировать точку и *, то можно сопоставить все символы. С помощью этой комбинации можно, например, заменить все символы в последней части строки: ed автоматически запоминает последнюю строку символов в шаблоне поиска или замененный текст. Однако вы должны подсказать ed, что нужно повторить замену, используя знак «%». Знак «%» позволяет вам сделать одинаковую замену во многих строках, не используя глобальной замены. Например, заменим слово money на слово gold, повторим последнюю замену в строках от 1 до 3:

ed автоматически запоминает слово money, так что строка не будет повторена между первыми двумя ограничителями. Знак «%» говорит ed — использовать последний шаблон для замены (gold).

6.16.6. Метасимволы [] (квадратные скобки)

Метасимволы «[]» позволяют определить подмножество символов, которые необходимо распознавать при выполнении операции поиска или подстановки. Запись группы символов, заключенных в квадратные скобки, означает: «любой одиночный символ из указанных». Например, если «[0123456789]», это будет означать: «любая цифра». Можно записать и короче: «8». Запись двух символов, разделенных знаком минус, означает задание интервала в

лексикографической последовательности символов. Так, запись «[А-Я]» означает: «прописная русская буква», а запись: «[a-z] [a-z0-9]*» означает последовательность латинских букв и цифр, начинающуюся с буквы.

Читайте также:  Install mysql connector linux

Указание в начале класса символа «^» означает «ни один из следующих символов». Например: обозначает «любой символ, за исключением цифры».

Примеры. удаление всех цифр в начале каждой строки; поиск первой строки, не начинающейся символом пробела или табуляции.

Внутри класса символов могут присутствовать любые символы и, чтобы избежать путаницы, в квадратных скобках символы принципиально не имеют специального значения. Например, чтобы найти специальные символы, можно использовать команду: Внутри «[. ]» символ «[» не является специальным. Чтобы включить символ «]» в класс символов, нужно указать его первым.

6.16.7. Метасимвол & (амперсенд)

Символ «&» используется в первую очередь для сокращения вводимого текста.

Предположим, имеется строка: и требуется преобразовать ее в строку: конечно, для этого можно воспользоваться командой: однако требование повторно указывать слово «ВРЕМЯ» кажется неразумным. Для того, чтобы избежать этого повторения, используется символ «&». В правой части команды подстановки амперсенд означает «найденный текст», так что можно ввести команду: где «&» будет означать «ВРЕМЯ». Конечно, в данном примере экономия будет незначительной, однако если количество символов велико или представляет собой нечто вроде «.*», которому соответствует большой кусок текста, экономится много вводимых символов. Снижается также вероятность совершения ошибки при вводе заменяющего текста. Например, для того, чтобы заключить в скобки строку, независимо от ее длины, можно использовать команду:

Амперсенд может встречаться в правой части команды несколько раз. Команда: построит строку: а команда: преобразует исходную строку в:

Чтобы получить настоящий символ «&», используется обратная дробная черта для отмены его специального значения. Команда: заменит слово «амперсенд» на символ «&». Обратите внимание на то, что символ «&» является специальным только в правой части команды, в левой части он не имеет специального значения.

Источник

EOF — это не символ

Недавно я читал книгу «Компьютерные системы: архитектура и программирование. Взгляд программиста». Там, в главе про систему ввода-вывода Unix, авторы упомянули о том, что в конце файла нет особого символа EOF .

Если вы читали о системе ввода-вывода Unix/Linux, или экспериментировали с ней, если писали программы на C, которые читают данные из файлов, то это заявление вам, вероятно, покажется совершенно очевидным. Но давайте поближе присмотримся к следующим двум утверждениям, относящимся к тому, что я нашёл в книге:

  1. EOF — это не символ.
  2. В конце файлов нет некоего особого символа.

Что же такое EOF ?

EOF — это не символ

Почему кто-то говорит или думает, что EOF — это символ? Полагаю, это может быть так из-за того, что в некоторых программах, написанных на C, можно найти код, в котором используется явная проверка на EOF с использованием функций getchar() и getc() .

Это может выглядеть так:

Если заглянуть в справку по getchar() или getc() , можно узнать, что обе функции считывают следующий символ из потока ввода. Вероятно — именно это является причиной возникновения заблуждения о природе EOF . Но это — лишь мои предположения. Вернёмся к мысли о том, что EOF — это не символ.

А что такое, вообще, символ? Символ — это самый маленький компонент текста. «A», «a», «B», «b» — всё это — разные символы. У символа есть числовой код, который в стандарте Unicode называют кодовой точкой. Например — латинская буква «A» имеет, в десятичном представлении, код 65. Это можно быстро проверить, воспользовавшись командной строкой интерпретатора Python:

Или можно взглянуть на таблицу ASCII в Unix/Linux:

Выясним, какой код соответствует EOF , написав небольшую программу на C. В ANSI C константа EOF определена в stdio.h , она является частью стандартной библиотеки. Обычно в эту константу записано -1 . Можете сохранить следующий код в файле printeof.c , скомпилировать его и запустить:

Скомпилируем и запустим программу:

У меня эта программа, проверенная на Mac OS и на Ubuntu, сообщает о том, что EOF равняется -1 . Есть ли какой-нибудь символ с таким кодом? Тут, опять же, можно проверить коды символов в таблице ASCII, можно взглянуть на таблицу Unicode и узнать о том, в каком диапазоне могут находиться коды символов. Мы же поступим иначе: запустим интерпретатор Python и воспользуемся стандартной функцией chr() для того, чтобы она дала бы нам символ, соответствующий коду -1 :

Как и ожидалось, символа с кодом -1 не существует. Значит, в итоге, EOF , и правда, символом не является. Переходим теперь ко второму рассматриваемому утверждению.

В конце файлов нет некоего особого символа

Может, EOF — это особенный символ, который можно обнаружить в конце файла? Полагаю, сейчас вы уже знаете ответ. Но давайте тщательно проверим наше предположение.

Возьмём простой текстовый файл, helloworld.txt, и выведем его содержимое в шестнадцатеричном представлении. Для этого можно воспользоваться командой xxd :

Как видите, последний символ файла имеет код 0a . Из таблицы ASCII можно узнать о том, что этот код соответствует символу nl , то есть — символу новой строки. Это можно выяснить и воспользовавшись Python:

Так. EOF — это не символ, а в конце файлов нет некоего особого символа. Что же такое EOF ?

Читайте также:  Редактор иконок для windows

Что такое EOF?

EOF (end-of-file) — это состояние, которое может быть обнаружено приложением в ситуации, когда операция чтения файла доходит до его конца.

Взглянем на то, как можно обнаруживать состояние EOF в разных языках программирования при чтении текстового файла с использованием высокоуровневых средств ввода-вывода, предоставляемых этими языками. Для этого напишем очень простую версию cat , которая будет называться mcat . Она побайтно (посимвольно) читает ASCII-текст и в явном виде выполняет проверку на EOF . Программу напишем на следующих языках:

  • ANSI C
  • Python 3
  • Go
  • JavaScript (Node.js)

Вот репозиторий с кодом примеров. Приступим к их разбору.

ANSI C

Начнём с почтенного C. Представленная здесь программа является модифицированной версией cat из книги «Язык программирования C».

Вот некоторые пояснения, касающиеся вышеприведённого кода:

  • Программа открывает файл, переданный ей в виде аргумента командной строки.
  • В цикле while осуществляется копирование данных из файла в стандартный поток вывода. Данные копируются побайтово, происходит это до тех пор, пока не будет достигнут конец файла.
  • Когда программа доходит до EOF , она закрывает файл и завершает работу.

Python 3

В Python нет механизма явной проверки на EOF , похожего на тот, который имеется в ANSI C. Но если посимвольно читать файл, то можно выявить состояние EOF в том случае, если в переменной, хранящей очередной прочитанный символ, будет пусто:

Запустим программу и взглянём на возвращаемые ей результаты:

Вот более короткая версия этого же примера, написанная на Python 3.8+. Здесь используется оператор := (его называют «оператор walrus» или «моржовый оператор»):

Запустим этот код:

В Go можно явным образом проверить ошибку, возвращённую Read(), на предмет того, не указывает ли она на то, что мы добрались до конца файла:

JavaScript (Node.js)

В среде Node.js нет механизма для явной проверки на EOF . Но, когда при достижении конца файла делается попытка ещё что-то прочитать, вызывается событие потока end.

Низкоуровневые системные механизмы

Как высокоуровневые механизмы ввода-вывода, использованные в вышеприведённых примерах, определяют достижение конца файла? В Linux эти механизмы прямо или косвенно используют системный вызов read(), предоставляемый ядром. Функция (или макрос) getc() из C, например, использует системный вызов read() и возвращает EOF в том случае, если read() указывает на возникновение состояния достижения конца файла. В этом случае read() возвращает 0 . Если изобразить всё это в виде схемы, то получится следующее:

Получается, что функция getc() основана на read() .

Напишем версию cat , названную syscat , используя только системные вызовы Unix. Сделаем мы это не только из интереса, но и из-за того, что это вполне может принести нам какую-то пользу.

Вот эта программа, написанная на C:

В этом коде используется тот факт, что функция read() , указывая на достижение конца файла, возвращает 0 .

Вот та же программа, написанная на Python 3:

Вот — то же самое, написанное на Python 3.8+:

Запустим и этот код:

Итоги

  • EOF — это не символ.
  • В конце файлов нет некоего особого символа.
  • EOF — это состояние, о котором сообщает ядро, и которое может быть обнаружено приложением в том случае, когда операция чтения данных доходит до конца файла.
  • В ANSI C EOF — это, опять же, не символ. Это — константа, определённая в stdio.h , в которую обычно записано значение -1.
  • «Символ» EOF нельзя найти в таблице ASCII или в Unicode.

Уважаемые читатели! А вы знаете о каких-нибудь более или менее широко распространённых заблуждениях из мира компьютеров?

Источник

EOF — это не символ

Недавно я читал книгу «Компьютерные системы: архитектура и программирование. Взгляд программиста». Там, в главе про систему ввода-вывода Unix, авторы упомянули о том, что в конце файла нет особого символа EOF .

Если вы читали о системе ввода-вывода Unix/Linux, или экспериментировали с ней, если писали программы на C, которые читают данные из файлов, то это заявление вам, вероятно, покажется совершенно очевидным. Но давайте поближе присмотримся к следующим двум утверждениям, относящимся к тому, что я нашёл в книге:

  1. EOF — это не символ.
  2. В конце файлов нет некоего особого символа.

Что же такое EOF ?

EOF — это не символ

Почему кто-то говорит или думает, что EOF — это символ? Полагаю, это может быть так из-за того, что в некоторых программах, написанных на C, можно найти код, в котором используется явная проверка на EOF с использованием функций getchar() и getc() .

Это может выглядеть так:

Если заглянуть в справку по getchar() или getc() , можно узнать, что обе функции считывают следующий символ из потока ввода. Вероятно — именно это является причиной возникновения заблуждения о природе EOF . Но это — лишь мои предположения. Вернёмся к мысли о том, что EOF — это не символ.

А что такое, вообще, символ? Символ — это самый маленький компонент текста. «A», «a», «B», «b» — всё это — разные символы. У символа есть числовой код, который в стандарте Unicode называют кодовой точкой. Например — латинская буква «A» имеет, в десятичном представлении, код 65. Это можно быстро проверить, воспользовавшись командной строкой интерпретатора Python:

Читайте также:  Ошибка активатора windows 10

Или можно взглянуть на таблицу ASCII в Unix/Linux:

Выясним, какой код соответствует EOF , написав небольшую программу на C. В ANSI C константа EOF определена в stdio.h , она является частью стандартной библиотеки. Обычно в эту константу записано -1 . Можете сохранить следующий код в файле printeof.c , скомпилировать его и запустить:

Скомпилируем и запустим программу:

У меня эта программа, проверенная на Mac OS и на Ubuntu, сообщает о том, что EOF равняется -1 . Есть ли какой-нибудь символ с таким кодом? Тут, опять же, можно проверить коды символов в таблице ASCII, можно взглянуть на таблицу Unicode и узнать о том, в каком диапазоне могут находиться коды символов. Мы же поступим иначе: запустим интерпретатор Python и воспользуемся стандартной функцией chr() для того, чтобы она дала бы нам символ, соответствующий коду -1 :

Как и ожидалось, символа с кодом -1 не существует. Значит, в итоге, EOF , и правда, символом не является. Переходим теперь ко второму рассматриваемому утверждению.

В конце файлов нет некоего особого символа

Может, EOF — это особенный символ, который можно обнаружить в конце файла? Полагаю, сейчас вы уже знаете ответ. Но давайте тщательно проверим наше предположение.

Возьмём простой текстовый файл, helloworld.txt, и выведем его содержимое в шестнадцатеричном представлении. Для этого можно воспользоваться командой xxd :

Как видите, последний символ файла имеет код 0a . Из таблицы ASCII можно узнать о том, что этот код соответствует символу nl , то есть — символу новой строки. Это можно выяснить и воспользовавшись Python:

Так. EOF — это не символ, а в конце файлов нет некоего особого символа. Что же такое EOF ?

Что такое EOF?

EOF (end-of-file) — это состояние, которое может быть обнаружено приложением в ситуации, когда операция чтения файла доходит до его конца.

Взглянем на то, как можно обнаруживать состояние EOF в разных языках программирования при чтении текстового файла с использованием высокоуровневых средств ввода-вывода, предоставляемых этими языками. Для этого напишем очень простую версию cat , которая будет называться mcat . Она побайтно (посимвольно) читает ASCII-текст и в явном виде выполняет проверку на EOF . Программу напишем на следующих языках:

  • ANSI C
  • Python 3
  • Go
  • JavaScript (Node.js)

Вот репозиторий с кодом примеров. Приступим к их разбору.

ANSI C

Начнём с почтенного C. Представленная здесь программа является модифицированной версией cat из книги «Язык программирования C».

Вот некоторые пояснения, касающиеся вышеприведённого кода:

  • Программа открывает файл, переданный ей в виде аргумента командной строки.
  • В цикле while осуществляется копирование данных из файла в стандартный поток вывода. Данные копируются побайтово, происходит это до тех пор, пока не будет достигнут конец файла.
  • Когда программа доходит до EOF , она закрывает файл и завершает работу.

Python 3

В Python нет механизма явной проверки на EOF , похожего на тот, который имеется в ANSI C. Но если посимвольно читать файл, то можно выявить состояние EOF в том случае, если в переменной, хранящей очередной прочитанный символ, будет пусто:

Запустим программу и взглянём на возвращаемые ей результаты:

Вот более короткая версия этого же примера, написанная на Python 3.8+. Здесь используется оператор := (его называют «оператор walrus» или «моржовый оператор»):

Запустим этот код:

В Go можно явным образом проверить ошибку, возвращённую Read(), на предмет того, не указывает ли она на то, что мы добрались до конца файла:

JavaScript (Node.js)

В среде Node.js нет механизма для явной проверки на EOF . Но, когда при достижении конца файла делается попытка ещё что-то прочитать, вызывается событие потока end.

Низкоуровневые системные механизмы

Как высокоуровневые механизмы ввода-вывода, использованные в вышеприведённых примерах, определяют достижение конца файла? В Linux эти механизмы прямо или косвенно используют системный вызов read(), предоставляемый ядром. Функция (или макрос) getc() из C, например, использует системный вызов read() и возвращает EOF в том случае, если read() указывает на возникновение состояния достижения конца файла. В этом случае read() возвращает 0 . Если изобразить всё это в виде схемы, то получится следующее:

Получается, что функция getc() основана на read() .

Напишем версию cat , названную syscat , используя только системные вызовы Unix. Сделаем мы это не только из интереса, но и из-за того, что это вполне может принести нам какую-то пользу.

Вот эта программа, написанная на C:

В этом коде используется тот факт, что функция read() , указывая на достижение конца файла, возвращает 0 .

Вот та же программа, написанная на Python 3:

Вот — то же самое, написанное на Python 3.8+:

Запустим и этот код:

Итоги

  • EOF — это не символ.
  • В конце файлов нет некоего особого символа.
  • EOF — это состояние, о котором сообщает ядро, и которое может быть обнаружено приложением в том случае, когда операция чтения данных доходит до конца файла.
  • В ANSI C EOF — это, опять же, не символ. Это — константа, определённая в stdio.h , в которую обычно записано значение -1.
  • «Символ» EOF нельзя найти в таблице ASCII или в Unicode.

Уважаемые читатели! А вы знаете о каких-нибудь более или менее широко распространённых заблуждениях из мира компьютеров?

Источник

Оцените статью