Лекция 7

 

Лекция 7. 1

Работа в ОС UNIX. 2

Интерпретаторы командной строки. Работа в Shell 2

sed. Классический потоковый редактор. 2

awk. Гибрид потокового редактора и алгоритмического языка программирования  4

Потоковые редакторы. Примеры.. 8

Распечатать первые 3 строки файла. 8

Заменить простые парные одинарные кавычки на русский вариант. 8

Преобразованию между форматами текстовых файлов в DOS и UNIX.. 8

Заменить расширения файлов `cpp’ на расширение `C’: 8

Подсчет числа слов в файле. 8

Подсчет числа слов и их упорядочение по частоте. 8

Подсчет числа слов и их упорядочение по алфавиту. 9

Разбор текстового файла с присваиваниями и выводом содержательных строк. 9

Создание таблицы из текстового файла. 9

Вывод имен файлов, отсортированными по размеру. 10

Вывод всех имен, использующихся include-файлов. 10

Поддержка однопользовательского проекта. Команда make. 11

Поддержка многопользовательского проекта. Команда cvs. 13

vi 15

Tags. 15

Использование. 16

Обработка ошибок. 16

Опции. 17

Команды.. 17

Режимы.. 17

Поиск. 18

Стереть. 18

Запомнить/вспомнить. 18

 


 

Работа в ОС UNIX.

 

Б.В.Кениган, Р.Пайк. UNIX --- универсальная среда программирования.

Финансы и статистика. Москва 92.

 

Джеймс Армстронг (мл.). Секреты UNIX. Диалектика. Киев 96.

 

Сергей Дунаев. UNIX. System V. Release 4.2. Диалог МИФИ, Москва 95г.

 

UNIX. X Window. Motif. ОСновы программирования (части I, II)

АО Аналитик. Москва 94.

 

 

 

Интерпретаторы командной строки. Работа в Shell

 

sed. Классический потоковый редактор

Программа, в которой можно задавать отдельные правила замены текста.

Формат:

sed [-n] [[-e] script ] [-f sfile ] [ file ] ...

где

-n           не выводить строки на стандартный поток вывода

-f sfile    читать программу из файла sfile

script     правила замены текста

 

Программа script, написанная на языке sed, применяется к каждой строке входного потока данных, после чего, строки (возможно, модифицированные) подаются на стандартный поток вывода.

Ключ -n приводит к тому, что строки на стандартный поток вывода не подаются. Ключ используется в случае, когда вывод осуществляется специальными операторами.

Отдельное правило замены оформляется в отдельной строке.

Общий формат команды

            [address [, address] ] function [arguments]

где address может быть следующим:

 

число                 номер строки, начиная с 1

$                         последняя строка;

/reular expr./       регулярное выражение

 

Пример:

 

sed -n '1,3p' t.c               распечатать первые 3 строки файла (`p’ = печатать)

 

sed "s/'\([^']*\)'/\`\1'/g" text       в файле text заменить простые парные одинарные кавычки       на, соответственно, открывающую и закрывающую кавычки (вариант, соответствующий правилам написания русского языка). Отметим, что в данном примере приходится отдельно экранировать обратную кавычку, которая не экранируется двойными кавычками.

Команды

y /string1/string2/          заменить символы из string1 на соответствующие символы из string2

s /sfrom/sto/flags           заменит строку sfrom на sto

g                      глобально для всей строки

   p                      распечатать результат (имеет смысл при наличии ключа n)

   w filename      записать в файл filename

 

 

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

 

tempf() { itmp=1; while [ -e $itmp ]; do itmp=1$itmp;done; echo $itmp; }     

 

dos2unix() { FILE=`tempf`; sed s/`printf '\015'`// fname >$FILE|;

             mv -f $FILE fname }

 

unix2dos() { FILE=`tempf`;

  sed "s/\([^`printf '\015'`]\)$/\1`printf '\015'`/" fname >$FILE;

  mv -f $FILE fname }

 

Заменить расширения файлов `cpp’ на расширение `C’:

for i in *.cpp; do mv $i `echo $i|sed ’s/^\(.\)\.cpp$/\1\.C/’`

 

 

Операторы в программе на языке sed разделяются с помощью `;’. Группы операторов могут объединяться в фигурные скобки.

Программы в sed допускают наличие меток и логических переходов.

Метки имеют синтаксис:

:label

Простой переход по указанной метке осуществляется с помощью оператора

b label

Условный переход осуществляется с помощью оператора

t label

Под условием подразумевается – была ли осуществлена замена в последнем операторе s///. Если была, то переход осуществляется, иначе – нет.

При отсутствии в операторах перехода метки переход осуществляется в конец тела программы.

 

В следующем примере в файле FILE строка, в которой найдено слова WORD обрамляется фигурными скобками:

sed 's/WORD/WORD/ ; t l1 ; b ; : l1 ; i \

\{

a \

\}

' FILE

 

Здесь использовались операторы i и a. Они вставляют указанный текст, соответственно, до и после текущей строки. Синтаксис:

i \

text

 

и

a \

text

 

Текущую обрабатываемую строку в sed называют pattern space.

В sed кроме текущей строки существует еще одна переменная, т.н. hold space. В него можно складывать текст, можно копировать/добавлять текст из текущей строки, можно копировать/добавлять текст из него в текущую строку.

Следующий простой пример собирает все строки из файла FileName, заканчивающиеся на `)’ (т.е., строки, похожие на описания функций) и выводит их в конце выводимого текста. Таким образом, можно собрать описания функций в программе на языке C.

 

sed '$,$ { p ; x ; } ; s/)$/)/ ; t l1 ; b ; :l1 H ; ' FileName

 

Здесь использовались операторы:

h / H       скопировать/добавить текущую строку к hold space

g / G       скопировать/добавить hold space к pattern space.

p             вывести содержимое pattern space.

x             поменять содержимое местами pattern space и hold space.

 

Этот же пример можно написать более коротко

sed ’${ /)$/{H} ж p ; x ; } ; /)$/{H}’

или, если нужно полученный список записать в файл FUNS,:

sed ’${ p ; x ; };$ w FUNS ; /)$/{ H }’

 

awk. Гибрид потокового редактора и алгоритмического языка программирования

awk сочетает в себе преимущества и потокового редактора, в котором можно активно использовать шаблоны, и языка программирования, в котором есть переменные, циклы, условные операторы и т.д. Как язык программирования awk , очень похож на язык С. Дадим очень короткое описание синтаксиса использования awk.

 

Формат вызова аналогичен формату sed:

awk [ options ] -f program-file [ - - ] file ...

или

awk [ options ] [  - -  ]  program-text file ...

 

Т.е. программа на языке awk может задаваться или в файле program-file (файлов может быть несколько, тогда перед именем каждого из них пишется ключ f; несколько файлов можно использовать для подключения библиотек), или в командной строке.

Внутрь программы на языке awk можно передавать переменные с помощью их определения в самой строке вызова awk. Для этого используется ключ

-v var=value

 

Программа состоит из инструкций, каждая из которых пишется в отдельной строке. Инструкция имеет вид:

pattern   { action statements }

где

pattern                           задает шаблон, определяющий, для каких строк применять инструкцию

action statements          набор операторов, который будет применен для каждой строки входного потока данных, отвечающей правилу pattern. Если операций несколько, то они разделяются точкой с запятой.

 

Переменные

 

Язык допускает использование переменных. Существует два типа переменных: вещественные и строковые. Переменные специально не определяются и не описываются. Определением переменной является ее первое появление в тексте. Тип определяется из контекста. Например, инструкция  x=10;  порождает вещественную переменную, а инструкция  x=”123”;  порождает строковую переменную.

Каждая строка из входного потока данных представляется как массив слов, к каждому из которых можно обратиться по его номеру. Символ-разделитель слов задается в переменной RS. По умолчанию слова разделяются пробелами. Символ-разделитель строк (полей) задается в переменной FS.

Обращение к i-тому слову: $i. В переменной NF хранится количество слов в строке. Величиной $0 обозначается вся строка, $1 – первое слово в строке, $NF – последнее слово.

В переменной NR хранится номер текущей строки.

 

Возможные виды шаблонов (pattern).

 

  BEGIN             действия, отвечающие данному шаблону выполняются один раз до обработки всех строк из входного потока данных

  END                 действия, отвечающие данному шаблону выполняются один раз после обработки всех строк из входного потока данных

  /regular expression/     расширенный вариант регулярных выражений, определенных выше

  relational expression   логическое выражение с использованием операторов == и !=

  pattern && pattern    

  pattern || pattern      

  pattern ? pattern : pattern

  (pattern)                   

  ! pattern                     

  pattern1, pattern2               сначала для каждой строки проверяется условие pattern1; если оно ложно, то считается, что текущая строка не удовлетворяет шаблону ; если оно истинно, то считается, что текущая строка удовлетворяет шаблону; далее каждая строка (начиная со следующей) проверяется на соответствие условию pattern2; пока это условие ложно, считается, что текущая строка удовлетворяет шаблону, иначе – строка не удовлетворяет шаблону. Далее опять проверяется условие pattern1. Здесь в качестве каждого шаблона можно указать просто номер строки.

 

 

Массивы

В языке используются ассоциативные массивы. Т.е. индексом массива является строка. Существуют только одномерные массивы. Аналог многомерных массивов получается путем задания списка индексов через запятую. В этом случае реальный индекс массива получается путем конкатенации перечисленных индексов с разделителем, содержащимся в переменной SUBSEP.

Пример. Подсчет числа слов во входном потоке

 

awk ”

BEGIN{N=0}

{N+=NF}

END{print ’Words number=’N}”

 

Возможны различные операции с массивами:

 

Var in Array      логическая операция in, проверяющая принадлежность Var индексам массива:

if (val in array)print array[val]

 

for (var in array) statement      цикл по индексам массива

 

delete array[index]                   уничтожение элемента массива с индексом index

 

delete array                               уничтожение массива

 

Пример. Сколько раз каждое слово встречается во входном потоке данных

 

awk ”

{for(i=1;i<=NF;i++)x[$i]++;}

END{for(i in x)printf  "#[%s]=%d\n",$i, x[$i]}”

 

Вывод

Функция print выводит свои аргументы с автоматическим переносом на следующую строку. При отсутствии аргументов выводится вся входная строка.

Функция printf является полным аналогом соответствующей функции в языке С.

Вывод можно перенаправлять в файл аналогично перенаправлению в Bash:

print x  >FileName

 

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

 

 

{for(i=1;i<=NF;i++)x[$i]++;}

END{for(i in x)printf  "#[%s]  %d\n",$i, x[$i]|”sort –g –r - -key=2”}

 

Здесь использовалась команда sort. Использовались следующие ключи этой команды

-g                       использовать числовое сравнение (general)

-r                        выводить в обратном порядке (reverse)

--key=NUM       использовать для сравнения поле с номером NUM

 

Работа со строками

Существует своя библиотека работы со строками. В следующем примере для каждой строки, в которой программа находит слово, лежащее в переменной word, под данной строкой выводится еще одна строка, содержащая подчеркивание всех вхождений данного слова в строке.

{

 i=index($0,"2");

 s[0]="";

 repl($0,s,1)

 printf ("%s\n%s\n", $0, s[0]);

}

function repl(str,rez,i0)

{

 if(i0<0)return;

printf("i0=%d\n",i0);

 s1=substr(str,i0);

 i=index(substr(str,i0),"2");

 if(i>0)

 {

  i+=i0-1;

  l0=length(rez[0]);

  for(j=0;j<(i-l0-1);j++)rez[0]=rez[0]" ";

  rez[0]=rez[0]"_";

  repl(str,rez,i+1);

 }

}

 

Здесь использовались функции

substr(s, i [, n])             возвращает подстроку строки s, начинающуюся с позиции i, содержащую не более n символов.

length     возвращает длину строки.

index(s, substr) возвращает номер позиции первого вхождения подстроки substr в строку s; при ненахождении возвращается 0.

Здесь везде позиции строки индексируются от 1.

Также полезны следующие функции:

split(s, a [, r]) разбивает строку s с помощью разделителей, задающихся регулярным выражением r, и помещает части разбиения в массив a; если регулярное выражение отсутствует, то разбиение производится значением переменной FS

gsub(r, s [, t])  глобальная замена выражений, задающихся регулярным выражением r на строку s в строке t; по умолчанию замена в текущей строке

sub(r, s [, t])     то же для первого вхождения

assort(m[,m2])  сортирует массив m , создает массив с отсортированными элементами исходного массива с целочисленными индексами и помещает его в массив m2, а при его отсутствии в m

assorti(m[,m2]) то же самое, но сортирует массив индексов исходного массива

Потоковые редакторы. Примеры

 

Распечатать первые 3 строки файла

sed -n '1,3p' t.c               распечатать первые 3 строки файла (`p’ = печатать)

Заменить простые парные одинарные кавычки на русский вариант

sed "s/'([^']*)'/`1'/g" text           в файле text заменить простые парные одинарные кавычки       на, соответственно, открывающую и закрывающую кавычки (вариант, соответствующий правилам написания русского языка).

 

Преобразованию между форматами текстовых файлов в DOS и UNIX

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

 

tempf() { itmp=1; while [ -e $itmp ]; do itmp=1$itmp;done; echo $itmp; }     

 

dos2unix() { FILE=`tempf`; sed s/`printf '015'`// $1 >$FILE|;

             mv -f $FILE $1 }

 

unix2dos() { FILE=`tempf`;

  sed "s/([^`printf '015'`])$/1`printf '015'`/" $1>$FILE;

  mv -f $FILE $1}

 

Заменить расширения файлов `cpp’ на расширение `C’:

for i in *.cpp; do mv $i `echo $i|sed ’s/^(.).cpp$/1.C/’`

 

Подсчет числа слов в файле

awk ”

BEGIN{N=0}

{N+=NF}

END{print ’Words number=’N}”

 

 

Подсчет числа слов и их упорядочение по частоте

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

 

{for(i=1;i<=NF;i++)x[$i]++;}

END{for(i in x)printf  "#[%s]  %dn",$i, x[$i]|”sort –g –r - -key=2”}

Подсчет числа слов и их упорядочение по алфавиту

Здесь используется функция сортировки индексов массива asorti:

 

{for(i=1;i<=NF;i++)m[$i]++;}

END{n=asorti(m,ind);for(j=1;j<=n;j++){print ind[j]"="m[ind[j]]}}

Разбор текстового файла с присваиваниями и выводом содержательных строк

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

Var=value

Переменные используются в тексте в виде ${Var}. Ссылки на переменную в тексте должны быть заменены на ее значение Value. Требуется вывести содержательный текст файла с заменой имен переменных на их значение.

 

function Exchange(s,V,  i){for(i in V){gsub("\\${"i"}",V[i],s);} return s;}

{

 n=split($0,m,"=");

 if(n==2)

 {

  m[2]=Exchange(m[2],V);

  V[m[1]]=m[2];

 }

 else

 {

  $0=Exchange($0,V)

  print

 }

}

Создание таблицы из текстового файла

Двумерные массивы не допускаются, но их можно заменить одномерными массивами, индекс которых состоит из двух индексов с символом-разделителем между ними:

{

 if(NFMax<NF)NFMax=NF

 for(i=1;i<=NF;i++)

 {  if(l[i]<length($i))l[i]=length($i);  m[NR,i]=$i; }

}

/*=========================*/

END{

/*for(i=1;i<=NFMax;i++)printf("l[%d]=%d\n",i,l[i]);*/

 for(i=1;i<NR;i++)

 {

  for(j=1;j<=NFMax;j++){printf("%-*.*s ",l[j],l[j],m[i,j])}

  printf("\n")

 }

}

Вывод имен файлов, отсортированными по размеру

Следующая команда выводит имена файлов в текущей папке вместе с размерами файлов, отсортированными по размеру файлов:

 

ls -l |awk '{print $5,$9}'|sort -g --key=1

в этой команде выводятся пятая и девятая колонки из данных, выводимых командой lsl  (соответственно, размер файла и имя файла). Далее строки сортируются по первому полю (ключ --key=1), используя сравнение чисел (ключ -g).

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

ls -l |grep -v '/'|awk '{print $5,$9}'|sort -g --key=1

в этой команде grep  ищет все строки, не содержащие подстроку '/' (ключ -v приводит к тому, что выводятся все строки, не отвечающие шаблону).

То же самое можно сделать с помощью задания шаблона в команде awk:

ls -l |awk '!///{print $5,$9}'|sort -g --key=1

 

Вывод всех имен, использующихся include-файлов

Следующая команда выводит имена всех include-файлов, использующихся в С-файлах, лежащих в подпапках текущей папки:

find . -name '*.C' -exec grep include '{}' ;|awk '{print $2}'|sed 's/["<](.*)[">]/1/'|sort|uniq

здесь команда find  ищет все файлы с расширением .C в текущей папке и подпапках текущей папки. Для найденных файлов запускается команда

grep include FileName

где FileName – имя найденного файла (FileName подставляется вместо символов {}). Далее awk выводит только второе слово из каждой переданной ему строки (первое слово – собственно `#include, второе – имя include-файла в кавычках). Далее sed убирает из оставшегося слова символ " или < из начала поданной ему строки и символ " или > из конца строки (в строке осталось всего одно слово – имя файла). Далее команда sort сортирует строки и команда uniq убирает повторяющиеся строки, расположенные друг за другом. В результате останутся только различные имена include-файлов.

Работу команды sed можно переложить на awk. Следующая команда выводит список только пользовательских include-файлов (т.е. файлов, имена которых заключаются в двойные кавычки):

find .  -name '*.C' -exec grep include '{}' ;|awk '/"/{i=index(substr($2,2),""");print substr($2,2,i-1)}'|sort|uniq

Для этого перед строкой с командой awk пишется шаблон /”/, в результате awk обрабатывает только строки, в которых содержится двойная кавычка. Выделение подстроки осуществляется командой substr, поиск подстроки командой index, т.е. команда index(substr($2,2),"""); ищет вхождение двойной кавычке во втором слове входной строки, начиная со второго символа в слове. Далее выводится данное слово начиная со второго символа (первая кавычка не выводится) до закрывающей кавычки (не включая ее).

 

Поддержка однопользовательского проекта. Команда make

 Для работы с большими проектами, выполняемыми одним пользователем, существует ряд инструментов. Наиболее часто используется команда make.

В основе идеологии команды лежит понятие дерева зависимостей. В его вершине лежит целевой файл (target file) (вообще говоря, целевых файлов может быть несколько; первый из них называется главным целевым файлом). В дочерних вершинах лежат исходные файлы (source files). В свою очередь, исходные файлы являются целевыми для файлов, лежащих в их дочерних вершинах. Предполагается, что целью создания проекта является создание главного целевого файла. Для его создания необходимы некоторые исходные файлы. Для создания исходных файлов необходимы еще некоторые файлы, которые лежат, соответственно, в дочерних к ним вершинам.

Например, нам требуется создать выполняемый файл prog. Для его создания нужны объектные файлы p1.o, p2.o, а для создания объектных файлов нужны, соответственно, файлы p1.c, p.h и p2.c, p.h. Дерево зависимостей выглядит следующим образом:

prog

p1.o                 p2.o

p1.c   p.h            p2.c  p.h

 

Имеется в виду, что если один из исходных файлов окажется модифицированным после времени последней модификации целевого файла, то данную зависимость следует обновить с помощью команды, которая указывается для каждой зависимости (т.е. для каждого целевого файла). Данный подход называется указанием явной зависимости.

Зависимость указывается с начала очередной строки. Целевой файл указывается в начале строки (с первой позиции), а далее, после двоеточия, указывается список исходных файлов через пробел. На следующей строке после символа табуляции (в DOS часто вместо символа табуляции достаточно написать некоторое количество пробелов) пишется команда, обновляющая данную зависимость:

 

prog : p1.o p2.o

            gcc –o prog p1.o p2.o

Когда команда make начинает свою работу, то она сначала считывает make-файл и строит дерево зависимостей. Целевой файл из первой найденной зависимости считается главным целевым файлом. Далее ищутся исходные файлы для файлов, являющихся исходными к главному целевому файлу, и т.д.

После того, как дерево зависимостей построено, начинается проверка зависимостей, начиная от листьев дерева. Если оказывается, что время последней модификации очередного целевого файла меньше времени последней модификации одного из исходных файлов, то выполняется команда, обновляющая зависимость. Обычно, если команда, обновляющая зависимость выдает ненулевой код возврата (т.е. компилятор обнаружил ошибки), то выполнение команды make прерывается.

В нашем случае полный make-файл может выглядеть следующим образом:

 

prog : p1.o p2.o

            gcc –o prog p1.o p2.o

p1.o : p1.c p.h

            gcc –c p1.c

p2.o : p2.c p.h

            gcc –c p2.c

 

Если исходных файлов много, то может быть использован механизм неявных зависимостей. При использовании этого механизма основная цель задается с помощью указания явных зависимостей. А дальше говорится о том, что каждый файл из предыдущих исходных файлов, имеющий определенное расширение, зависит от файла с тем же именем, но другим заданным расширением. Например, в нашем случае, говорится, что каждый файл с расширением .o зависит от файла с тем же именем и расширением .c:

 

.c.o

            gcc –c $<

 

при этом используются следующие обозначения:

 

$*        имя целевого файла без расширения

$@       имя целевого файла с расширением

$<        имя исходного файла

$?         список имен исходных файлов

 

 

make-файл может служит для разнообразных целей. Если команда  make вызывается без параметров, то считается, что в качестве make-файла выступает файл с именем makefile или Makefile (возможно, ищутся еще некоторые имена) и в качестве основной цели выступает первая найденная цель в файле. Иное имя make-файла  можно задать после ключа f,  а другую главную цель можно выбрать, просто указав ее имя в качестве параметра команды make. Например, для обычных проектов принято указывать цель clean. Предполагается, что файла с таким именем не существует, и если мы наберем команду

make clean

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

make clean

            rm –f *.o prog

 

 Поэтому, если после данной команды вызвать команду make без параметров, то произойдет полная перекомпиляция проекта.

 

Поддержка многопользовательского проекта. Команда cvs

 Для работы с большими проектами, поддерживаемыми несколькими пользователями, существует ряд инструментов. Наиболее часто используется программа cvs (Concurrent Versions System). cvs позволяет нескольким пользователям создавать параллельно один проект. cvs создает базу данных (репозиторий), в которой хранится информация обо всех изменениях, происшедших в проекте, отслеживая их в определенные моменты времени. Если различные пользователи модифицируют различные файлы, то cvs позволяет синхронизировать эти изменения. Если пользователи модифицируют один файл, то cvs пытается совместить все эти независимые изменения.

Указать на папку, в который размещается репозиторий, можно с помощью соответствующей переменной среды:

export CVSROOT=/usr/src/master

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

Инициализация репозитория:
cvs init
 
Создание папки и помещение ее в репозиторий:
cvs co -l .
mkdir hello
cvs add hello

 

Перенести уже готовую папку в репозиторий можно командой:

cd hello

cvs import hello tag1 tag2

где tag1 - тэг производителя, tag2 - тэг релиза (это – обязательные параметры). В первом случае helloимя папки, из которой мы переносим данные, а во втором hello – имя, под которым текущая папка будет помещена в репозиторий (имена могут отличаться!!!). Эту же команду можно использовать для помещения пустой папки в репозиторий, т.е. для инициализации работы с ней.

Новый пользователь должен получить свою версию проекта. Для этого используется команда checkout:

cvs checkout hello

данная команда извлечет папку hello из репозитория и поместит ее в текущую папку данного пользователя. Отметим, что в этой папке будет создана подпапка CVS со служебной информацией для cvs.

 

 

Основные команды:

add                  добавить файл в репозиторий

remove                        извлечение файла из репозитория

update             перенести изменения, внесенные другими пользователями в репозиторий, в свою версию проекта

commit            внести свою версию проекта в репозиторий

 

 

Добавление файла в репозиторий:
cvs add hello.c

 Отметим, что файлы и папки (папки в смысле – просто папки, т.е. без вложенных файлов) переносятся в репозиторий только по специальному запросу. И это правильно, т.к. в любом проекте есть много файлов, хранить которые часто нет никакого смысла (например, объектные файлы).

Извлечение данных из репозитория в текущую версию программы (в случае если кто-то еще исправлял файл):
cvs update hello.c

Имя файла можно не указывать и тогда команда cvs update перенесет все изменения, внесенные в репозиторий в вашу версию проекта.

Если возник конфликт (кто-то исправил тот же файл, что и вы и сделал это в том же месте, что и вы), то вам об этом будет сообщено. При этом, в ваш файл будет помещено оба варианта исправленного текста: и ваш и тот, который внес в репозиторий кто-то другой. Текст файла, объединяющего две версии, будет примерно следующим:

 
 
<<<<<<< 
текст вашей версии
======= 
текст версии, которую кто-то внес в репозиторий
>>>>>>> 

 

Информация о том, с кем конкретно у вас вышел конфликт, будет выведена непосредственно на экран после вызова команды cvs update.

 

Если конфликт устранен (т.е. вы договорились лично с кем-то, кто внес другую версию в репозиторий), то в файле следует оставить конечный вариант текста и вызвать команду, переносящую окончательную версию файла (файлов) в репозиторий:

cvs commit hello.c

Как и ранее, команда cvs commit перенесет все изменения в вашей версии проекта в репозиторий. При этом, новая версия получит очередной номер и будет вызван редактор для того, чтобы вы могли внести краткое описание внесенных изменений. Описание новой версии можно передать и в самой команде после ключа -m.

 

Можно просто сравнить версию файла (или всех файлов – если не указывать имя файла) в репозитории и в вашей версии проекта:

cvs diff -u hello.c

 Можно сравнить две различные версии файла (или всех файлов – если не указывать имя файла):

cvs diff -r 1.6 -r 1.7 hello.c
здесь сравниваются версии 1.6 и 1.7 файла hello.c.

 

 

vi

Tags

 

Создаются командой ctag FileName

 

Типы тагов (gcc):

           macro definitions (i.e. names created by #define)

           enumerated values (i.e. the values inside enum{...})

           function definitions                                 

           function prototypes or declarations (optional)         

           class, enum, struct and union tags                        

           typedefs                                                   

           variables                                                    

 

Типы тагов RS6000 --- только ф-ции.

 

Вид таг-файла:

 

tag-name  TAB file-name TAB execute-command

 

Options:

 

-a      Append the tags to an existing tag file.   (All cc)

 

-e      Output  tag  file for use with Emacs.

 

-f tagfile

 

-L listfile    Read from listfile a list of  file  names

 

-n       Places into the tag file line numbers

 

Использование

 

vi -t tag  

 

Control-]      в tag-файле: найти ссылку, на которой стоит курсор.

 

:ta tag        в текущем файле: найти tag с именем tag .

 

Обработка ошибок

 

vi -e [errorfile|errors.vim]

 

:cn    Next error

 

:cp    Previous error

 

Пример:

 

 

gcc t.c 2>errors.vim

vi -e

 

Надо компилировать с опцией -qf .  If the compiler finds any errors, Vim is

  started and the cursor is positioned on the first error.

 

:cq --- Выйти из редактора, иначе при выходе --- перекомпиляция

 

:cc[!] [nr] --- перейти на ошибку nr; ! --- нужен если надо переходить в др.файл

 

:cl[ist] ---                List all errors that inlcude a file name

 

:cl[ist]! ---              List all errors.

 

:make ---  executes the command given with the 'makeprg'  option

 

:set makeprg=make$backslash$ $backslash$%$<$.o ---  $backslash$% --- имя тек.файла

 

pagebreak

 

 

Опции

 

-c {command} or +{command} --- :command выполняется перед редактированием файла

 

Команды

 

CTRL-Z --- прерывает выполнение; далее --- fg

 

 Режимы

 

iI

oO

аA

rR

 

 

Стрелки:

(Left arrow) or h

(Down arrow) or j or Ctrl-J or Ctrl-N    

(Up arrow) or k or Ctrl-P

(Right arrow) or l

 

fx --- на символ x

 

  H          --- Moves the cursor to the top line on the screen.

 

  L          --- Moves the cursor to the last line on the screen.

 

  M         --- Moves the cursor to the middle line on the screen.

 

 

  Ctrl-U   Scrolls up one-half screen.

 

  Ctrl-D   Scrolls down one-half screen.

 

  Ctrl-F   Scrolls forward one screen.

 

  Ctrl-B   Scrolls backward one screen.

 

 

U --- undo

 

CTRL-A --- вставить текст который до этого был между I & ESC (vim).

 

 

 

Поиск

 

f [n] x  --- найти символ x в строке (n раз); `;' --- повторить

 

/Pattern

 

?Pattern

 

n

 

N --- повтор назад

 

% --- закрывающаяся скобка

 

 

Стереть

 

  D          --- Deletes the rest of the line

 

  dd         --- Deletes a line.

 

  dw        --- Deletes a word.

 

  J           --- Joins lines.

 

pagebreak

 

 Запомнить/вспомнить

 

  yMOTION       --- поместить все от текущей позиции до

позиции после команды  MOTION (for example, w for word)

в буфер

 

  Y          --- Places the line in the undo buffer.

 

  p           --- Puts back text from the undo buffer after the cursor.

 

  P          --- Puts back text from the undo buffer before the cursor.

 

 

{bf Чтение/запись}

 

  :w

 

  :w --- File        

 

:e --- File            Edits the specified file

 

:e!           --- Re-edits the current file and discards all changes.

 

:e #         --- Edits the alternate file

 

:r File      --- Reads the file

 

:r !Command      

 

:!Command        

 

:n            --- Edits the next file (если их было несколько)

 

:[range:]s/from/to/{p,g}

 

{bf range}

 

*  --- для одной строки

*,*  --- для диапазона

 

где *:

 

/pattern/ or line-num or:

 

.              --- the current line                                  

$             --- the last line in the file                         

%                       --- equal to 1,$ (the entire file)               

$*$                     --- equal to '$<$,'$>$ (the Visual area)  

't             --- position of mark t (lower case)                     

/{pattern}[/]        --- the next line where {pattern} matches           

?{pattern}[?]      --- the previous line where {pattern} matches

 

Можно писать что-то+N

 

Cntrl+V  (vim) --- начать выделение блока (y --- запомнить, d --- del, p --- insert)

pagebreak