2013-04-15 2 views
1

РЕДАКТИРОВАТЬ # 1: Я не могу ограничиться тем, что все аргументы заключены в две кавычки, так что оболочка не расширяет аргумент с * до соответствующего пути.Как я могу реализовать команду 'ls' с подстановочным знаком '*'?

EDIT # 2: Для того, чтобы восстановить каталоги, такие как */*, ../* и dirA/*/file.out, Как я должен использовать итерации цикла или рекурсивный вызов?

Я только что узнал о функции fnmatch(). Но я не знаю места начала.
Существует много возможных случаев. Я смущен, имея дело с этими делами.
Например, допустим, что исполняемая программа - a.out.

$./a.out -l */* 
$./a.out -l ../* 
$./a.out -l [file_name] [directory_name] 
/* Since I also have to implement ls command with no wildcard. */ 

Что мне делать? Любые советы были бы замечательными.
Спасибо заранее.

+0

Вы должны знать, что ваша оболочка расширяет '*' до того, как она получит ваш исполняемый файл ... – geoffspear

+0

Быстрое примечание: большинство оболочек заменяет собой себя. Когда вы запускаете 'ls *' в bash, аргументы, ls' принимает имена всех файлов в текущем каталоге, а не '*'. Чтобы обеспечить эту функциональность, вам придется избегать ваших аргументов. – pistache

ответ

0

Ваша проблема: оболочка заменяет шаблон шаблона * всеми именами файлов, соответствующими шаблону.

Решение:

Если вы не хотите использовать эту особенность Баш, просто поставить кавычки вокруг аргументов командной строки.

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

После этого вы можете перечислить все имена файлов с их путями. Например, используя некоторый рекурсивный алгоритм. Затем вы можете применить некоторое соответствие к этой строке пути. (при посещении)

0

Если вы хотите быть хорошим гражданином unix, правило Не делайте имя файла, если вы не пишете оболочку.

Вы хотите написать ls-подобную программу? Не делайте никаких подстановочных расширений. Не используйте «*» специально. Просто обработайте свой argv как список имен файлов. Если ваша программа обрабатывает эти случаи:

./a.out file1 
./a.out file1 file2 file3 

Затем он обрабатывает

./a.out file* 

правильно, потому что оболочка будет делать расширение и ваша программа не нужно будет знать об этом. И, кроме того, он будет обращаться с этим:

zsh% ./a.out **/file<40-185>~file<90-100>(.mm-30OL[1,2]) 

который в Zsh расширен синтаксис Глоб означает: расширение file40 через file185, кроме file90 через file100, включают в себя только те, которые были изменены в течение последних 30 минут, используйте только самые большие 2 файла в результирующем наборе.

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

Когда вы находитесь в ситуации, когда вы не можете взять список имен файлов из командной строки, рассмотрите возможность использования fnmatch. ls не является одной из таких ситуаций.

+0

Есть * некоторые * другие команды, которые делают свое собственное расширение подстановки, например 'find'. –

+0

@KeithThompson уверен, что есть исключения, и 'find' является большим, так как поиск файлов является его центральной целью. И такие вещи, как 'unzip', хотят хранить имена, существующие в архиве, а не файловую систему. Но реакция на «Я реализую ls с подстановочными знаками» должна быть «ARGH NO!» –

Смежные вопросы