Pull to refresh

Unix как IDE: Файлы

Reading time 5 min
Views 28K
Original author: Tom Ryder
Одной из важных особенностей IDE является встроенная система управления файлами. Она должна включать в себя как базовые возможности, такие как переименование, удаление перемещение, так и более специфические для разработки: компиляция и проверка синтаксиса. Вдобавок было бы удобно оперировать группами файлов для поиска по размеру, расширению или по маске. В этой первой статье я покажу несколько вариантов использования инструментов, знакомых любому пользователю Linux, для работы с группами файлов в проекте.


Списки файлов


Администратор знакомится с командой ls одной из первых, чтобы с ее помощью просматривать простой список содержимого директории. Многие администраторы также умеют использовать ключи -a и -l, чтобы вывести все файлы, включая '.' и '..', и чтобы отобразить более детальные сведения о файлах по колонкам, соответственно.

Существует еще несколько ключей для ls, несколько реже используемых, но очень полезных для целей программирования:
  • -t — Вывести файлы, выстроенные по дате последней модификации в порядке убывания. Ключ полезен для очень больших директорий, когда нужно быстро получить список самых последних отредактированных файлов, возможно пропущенных через head или sed 10q. Наверное, наиболее полезен в связке с -l. Если нужны самые старые файлы, можно добавить -r и тем самым перестроить список в обратном порядке.
  • -X — Группировать файлы по расширению. Полезно для многоязычной разработки, для отделения заголовочных файлов от основного кода, для отделения файлов кода от директорий или от сборочных файлов.
  • -v — Позволяет легко сортировать номера версий в именах файлов.
  • -S — Сортировка по размеру файла.
  • -R — Вывести список файлов рекурсивно, включая подкаталоги. Этот ключ хорош в связке с -l и перенаправлением вывода на постраничную листалку вроде less.


Поскольку список файлов — это обычный текст, можно направить его поток в vim, где добавить пояснения к каждому файлу, а потом сохранить текст в качестве описи или добавить в README:

$ ls -XR | vim -


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

Поиск файлов


Как ни странно, можно получить полный список файлов, включая относительные пути, просто напечатав "find" без аргументов, хотя обычно лучше выстроить их по порядку при помощи sort:

$ find | sort

.
./Makefile
./README
./build
./client.c
./client.h
./common.h
./project.c
./server.c
./server.h
./tests
./tests/suite1.pl
./tests/suite2.pl
./tests/suite3.pl
./tests/suite4.pl


Если хотите вывести файлы подобно ls, можно добавить -ls:

$ find -ls | sort -k 11
1155096    4 drwxr-xr-x   4 tom      tom          4096 Feb 10 09:37 .
1155152    4 drwxr-xr-x   2 tom      tom          4096 Feb 10 09:17 ./build
1155155    4 -rw-r--r--   1 tom      tom          2290 Jan 11 07:21 ./client.c
1155157    4 -rw-r--r--   1 tom      tom          1871 Jan 11 16:41 ./client.h
1155159   32 -rw-r--r--   1 tom      tom         30390 Jan 10 15:29 ./common.h
1155153   24 -rw-r--r--   1 tom      tom         21170 Jan 11 05:43 ./Makefile
1155154   16 -rw-r--r--   1 tom      tom         13966 Jan 14 07:39 ./project.c
1155080   28 -rw-r--r--   1 tom      tom         25840 Jan 15 22:28 ./README
1155156   32 -rw-r--r--   1 tom      tom         31124 Jan 11 02:34 ./server.c
1155158    4 -rw-r--r--   1 tom      tom          3599 Jan 16 05:27 ./server.h
1155160    4 drwxr-xr-x   2 tom      tom          4096 Feb 10 09:29 ./tests
1155161    4 -rw-r--r--   1 tom      tom           288 Jan 13 03:04 ./tests/suite1.pl
1155162    4 -rw-r--r--   1 tom      tom          1792 Jan 13 10:06 ./tests/suite2.pl
1155163    4 -rw-r--r--   1 tom      tom           112 Jan  9 23:42 ./tests/suite3.pl
1155164    4 -rw-r--r--   1 tom      tom           144 Jan 15 02:10 ./tests/suite4.pl



Заметьте, в данном случае мне пришлось дать указание сортировать по 11 колонке вывода, то есть по именам файлов; для этого используется ключ -k.

У find довольно сложный синтаксис встроенного фильтра. Следующие примеры показывают несколько самых полезных, которые можно применять для получения нужного списка файлов:
  • find -name '*.c' — найти файлы с именами согласно маске в стиле shell. Можно использовать -iname для регистронезависимого поиска.
  • find -path '*test*' — найти файлы, путь к которым совпадает с маской. Можно использовать -ipath для регистронезависимого поиска.
  • find -mtime -5 — найти файлы, отредактированные за последние 5 дней. Можно использовать +5 чтобы найти файлы, измененные раньше, чем 5 дней назад.
  • find -newer server.c — найти файлы, измененные раньше, чем server.c.
  • find -type d — найти директории. Для поиска файлов используется -type f; для символических ссылок -type l


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

$ find -name '*.c' -mtime -2

Над найденными файлами find может выполнять разные действия. По умолчанию это направление списка в стандартный поток вывода, но есть несколько других вариантов:
  • -ls — Выдать список в стиле ls -l.
  • -delete — Удалить найденные файлы.
  • -exec — Выполнить произвольную командную строку над каждым файлом, где {} будет заменено на соответствующее имя файла, и признаком окончания которой служит \;, например:
    $ find -name '*.pl' -exec perl -c {} \;
    

    В большинстве случаев проще применить xargs, чтобы результат превратился в аргументы для команды:
    $ find -name '*.pl' | xargs perl -c
    

  • -print0 — если у вас есть файлы с пробелами в именах, и вы хотите передать их в xargs подобно предыдущему примеру, то используйте этот ключ, и разделителем записей будет назначен 0-символ вместо пробела. Одновременно с этим xargs должен запускаться с ключом -0:
    $ find -name '*.jpg' -print0 | xargs -0 jpegoptim
    


    Я часто пользуюсь следующим трюком для генерации списков, которые затем можно редактировать в окнах Vim, делящих экран по вертикали:

    $ vim -O $(find . -name '*.c')


Иной поиск файлов



И все же гораздо чаще, чем по внешним атрибутам, требуется искать файлы, опираясь на их содержимое, и здесь grep, а особенно grep -R, спешит на помощь. Эта команда рекурсивно ищет в текущей директории все, что совпадает с указанным текстом:

$ grep -FR 'someVar' .


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

$ grep -iR 'somevar' .


Можно также вывести список файлов, содержащих совпадения, без самих совпадающих строк при помощи grep -l. Это, опять же, удобно при построении списка файлов для дальнейшего редактирования в текстовом редакторе:

$ vim -O $(grep -lR 'somevar' .)


Если в проекте используется контроль версий, то все метаданные обычно содержатся в папках .svn, .git или .hg. Можно без труда исключить (grep -v) ненужные элементы при помощи сравнения с фиксированной строкой (grep -F):
$ grep -R 'someVar' . | grep -vF '.svn'

Существует очень популярная альтернатива grep, именуемая ack, которая по умолчанию исключает всю подобную шелуху. Ack также позволяет использовать Perl-совместимые регулярные выражения (PCRE), столь любимые многими хакерами. Она располагает очень удобными средствами работы с исходниками. Несмотря на то, что со старым добрым grep нет никаких проблем, поскольку он всегда под рукой, при возможности очень советую установить Ack. Для всех популярных Unix-систем есть соответствующий пакет в стандартных репозиториях.

Принципиальные поклонники Unix, скорее всего, огорчены упоминанием такой сравнительно новой альтернативы grep, да еще и в виде Perl-скрипта. Однако мне не хотелось бы думать, что философия Unix и, в частности, идея использования Unix как IDE обязательно означает отказ от близких по духу современных альтернатив, способных решать актуальные проблемы.

Метаданные файлов



Утилита file выводит одной строкой сводную информацию о файле на основе расширения, заголовков и других признаков. Это очень удобно при совместном использовании с find и xargs для изучения групп незнакомых файлов:
$ find | xargs file
.:            directory
./hanoi:      Perl script, ASCII text executable
./.hanoi.swp: Vim swap file, version 7.3
./factorial:  Perl script, ASCII text executable
./bits.c:     C source, ASCII text
./bits:       ELF 32-bit LSB executable, Intel 80386, version ...

Поиск по шаблону


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

Все вышеперечисленное наделяет оболочку Unix довольно мощными средствами управления файлами при написании программ.

Продолжение следует...

Unix как IDE: Введение
Unix как IDE: Файлы
Unix как IDE: Работа с текстом
Unix как IDE: Компиляция
Tags:
Hubs:
+47
Comments 35
Comments Comments 35

Articles