ls | sort -r
и на экране появиться отсортированный список файлов и подкаталогов. Эта командная строка намного короче и не требует создания ненужных файлов.
Другой полезный пример.
Команда
ls /usr/bin
выдает на дисплей длинный список имен файлов, большинство из которых слишком быстро исчезают с экрана, и Вы не успеваете прочитать их. Подключите к просмотру перечня имен файлов каталога /usr/bin команду more:
ls /usr/bin | more
Теперь Вы можете постранично листать файл в свое удовольствие.
Вы можете связать в конвейер более двух команд. В примере используется команда head, которая отображает первые заданные строки входного потока в стандартный выходной поток. Если Вы хотите отобразить на экране последнее имя из списка текущего каталога, упорядоченного по алфавиту, Вы можете ввести следующую командную строку:
ls | sort -r | head -1
где head -1 просто выдает первую строку (-1) получаемого входного потока (в данном случае это отсортированный в обратном порядке перечень имен файлов текущего каталога, выданных командой ls).
4. Перенаправление с добавлением.
Использование ">" для перенаправления выхода смертельно для файла, в который происходит перенаправление (если этот файл уже существует). Например,
ls > file-list
уничтожит прежнее содержимое файла file-list. Убедитесь, что теперь файл file-list содержит лишь список имен файлов и подкаталогов текущего каталога в алфавитном порядке, набрав команду
cat file-list
Если вместо ">" использовать символ перенаправления ">>", выходной поток будет добавлен к содержимому указанного файла (а не записан на место уже хранящейся в нем информации).
ls >> pokupki
В формате MS Word 97
1. Продолжение работы с shell.
1. Простейшие циклы shell.
Типичным считается цикл по последовательности имен файлов, и оператор shell for является единственной структурой управления, которую обычно задают с терминала, а не помещают в файл для последующего выполнения. Синтаксис оператора for таков:
for переменная in список_слов
do
команды
done
Например, для вывода на экран имен файлов по одному на строке достаточно задать следующий цикл:
for i in *
do
echo $i
done
Вместо i можно применять любую переменную shell, но это обозначение традиционно. Заметьте, что обращение к переменной задается с помощью $i, однако в заголовке цикла переменная указывается как i. Значения переменной i определены шаблоном * (для выбора всех файлов текущего каталога).
Выходной поток цикла можно перенаправить в файл, используя символ перенаправления:
for i in *
do
echo $i
done > spisok
в результате будет создан файл spisok, содержащий список имен файлов текущего каталога по одному на строке. Проверьте, так ли это?
Выходной поток цикла можно направить и по конвейеру. Чтобы получить на экране отсортированный список файлов достаточно сделать следующее:
for i in *
do
echo $i
done | sort
Указав соответствующую опцию команды sort, Вы сможете отсортировать список в нужном Вам порядке.
Всю последовательность команд цикла можно запускать в фоновом режиме, указав в конце символ &. & применяется ко всякому циклу и конвейеру.
Можно использовать другой формат для цикла for. Единственное ограничение заключается в том, что do и done распознаются как ключевые слова только в том случае, если они появляются сразу после перевода строки или точки с запятой. В зависимости от размера цикла for иногда лучше помещать его на одной строке:
for i in список_значений; do команды; done
Список аргументов для цикла for часто получают путем выбора имен файлов по шаблону, но можно получать и любым другим способом, в частности, просто вводом аргументов.
Например, ранее Вы создали ряд программ для печати в несколько столбцов под именами 2, 3 и т.д. Все программы, кроме 2, являются связями с файлом 2. Поэтому, если скрипт 2 создан, то связи можно установить с помощью цикла for:
for i in 3 4 5 6 7 8; do ln 2 $i; done
Теперь Вы сможете выводить файлы в 3, 4, 5 , 6 , 7 и 8 столбцов.
2. Совершенствование команды саl.
shell позволяет сделать взаимодействие между пользователем и программой более удобным. В качестве примера рассмотрим команду саl. Вы помните, как используется эта команда: саl [month] year. Однако досадно, что месяц нужно задавать числом:
саl october
Реакция программы на такую команду:
bad argument
(неверный аргумент).
К тому же команда
саl 10
выдает календарь на весь 10-й год, а не на октябрь текущего года. Поэтому всегда следует указывать год, если Вы хотите получить календарь на один месяц.
Вы можете изменить характер взаимодействия пользователя с программой саl, не меняя самой программы.
Первый шаг разработки - определить функции усовершенствованной команды саl:
· месяц нужно распознавать по названию;
· при наличии двух аргументов команда должна делать то же, что делала прежняя версия, за исключением перевода названия месяца в его номер;
· в случае одного аргумента следует печатать календарь месяца или года (в зависимости от того, что Вам требуется);
· а при отсутствии аргументов - календарь текущего месяца, так как большей частью именно для этого и обращаются к команде.
Поэтому задача сводится к тому, чтобы определить, сколько аргументов задано, и преобразовать их в те параметры, которые требуются стандартной команде cal.
shell имеет оператор case, который успешно применяется в таких ситуациях:
case слово in
шаблон) команды ;;
шаблон) команды ;;
…
esac
В операторе case значение слово сравнивается поочередно со всеми шаблонами от начала до конца, и выполняются команды, связанные с первым (и только первым) шаблоном, соответствующим слову. Шаблоны составляются по правилам соответствия шаблонов, которые в некоторой степени обобщают правила задания имен файлов. Каждое действие завершается двумя символами ;; (для последнего варианта можно обойтись без ;;, но обычно их ставят для удобства редактирования).
В новой версии команды саl определяется число заданных аргументов, обрабатываются названия месяцев, затем происходит обращение к настоящей команде саl.
В переменной интерпретатора $# хранится число аргументов, с которыми была вызвана программа. Символ # в начале слова означает, что вся следующая за ним строка рассматривается как комментарий.
В своем личном каталоге bin с помощью редактора vi создайте файл саl, содержание которого следующее:
# cal: улучшенное взаимодействие с /usr/bin/cal
case $# in
0) set `date`; m=$2; y=$7;; # нет аргументов: использует текущие
1. m=$1; set `date`; y=$7;; # 1 аргумент: использует текущий год
*) m=$1; y=$2;; # 2 аргумента: месяц и год
esac
case $m in
jan* | Jan*) m=1;;
feb* | Feb*) m=2;;
mar* | Mar*) m=3;;
apr* | Apr*) m=4;;
may* | May*) m=5;;
jun* | Jun*) m=6;;
jul* | Jul*) m=7;;
aug* | Aug*) m=8;;
sep* | Sep*) m=9;;
oct* | Oct*) m=10;;
nov* | Nov*) m=11;;
dec* | Dec*) m=12;;
[1-9]|10|11|12) ;; # номер месяца
*) y=$m; m=" ";; # обычный год
esac
/usr/bin/cal $m $y # запуск настоящей команды
В первом операторе case проверяется число аргументов $# и выбирается подходящее действие. Последний шаблон в этом операторе задает вариант, выбираемый по умолчанию: если число аргументов не 0 и не 1, будет выполнен последний вариант. (Поскольку шаблоны выполняются по порядку, вариант по умолчанию должен быть последним.) При наличии двух аргументов m и у принимают значения месяца и года, и новая команда должна выполняться как исходная команда.
Первый оператор case включает пару нетривиальных строк, содержащих set `date`. Хотя сразу это и не очевидно, легко установить действие команды, запустив ее. Вы помните, что команда date выводит на экран информацию о дне недели, месяце и числе, времени и годе. Для большей наглядности Вы можете сначала выполнить команду
date
а затем ввести
set `date`
А после проверьте результаты ее выполнения, введя следующие команды:
echo $1
на эране должно появиться название текушего дня недели;
echo $4
Вы должны увидеть текущее время.
Команда set - встроенная команда интерпретатора, возможности которой многообразны. При отсутствии аргументов она выдает, как Вы помните, значения переменных среды. В случае обычных аргументов переопределяются значения $1, $2 и т.д. Поэтому set `date` присваивает $1 - день недели, $2 - название месяца и т.д. Таким образом, при отсутствии аргументов в первом операторе case месяц и год устанавливаются из текущей даты. Если задан один аргумент, он используется в качестве месяца, год берется из текущей даты.
Теперь осталось только перевести значение месяца, если оно представлено в строковом виде, в число. Это делается с помощью второго оператора case, который практически очевиден. Единственный нюанс состоит в том, что символ | в шаблонах оператора case означает альтернативу: малый | большой соответствует варианту малый или большой. Конечно, эти варианты можно было бы задать с помощью [jJ]an* и т. д.
Программа допускает задание месяца строчными буквами, поскольку большинство команд работает с входным потоком, где данные записаны строчными буквами, иногда первая буква—прописная, поскольку так выглядит вывод команды date.
Правила сопоставления шаблонов в интерпретаторе
* задает любую строку, включая пустую
? задает любой одиночный символ
[ссс] задает любой из символов в ссс [a-d0-3] эквивалентно [abcd0123]
" ... " задает в точности ...; кавычки защищают от специальных символов. Аналогично действуют '...'
\с задает с буквально (т.е. отвергает специальное значение символа)
a | b только для выражений выбора; задает а или b
Два последних варианта второго оператора case относятся к случаю, когда единственный аргумент может быть годом; напомним, что в первом операторе case предполагалось, что аргументом является месяц. Если это число, которым может быть задан месяц, то ничего не происходит (иначе предполагается, что задан год).