#command-line-arguments #glob #raku #command-line-tool
Вопрос:
Я хотел бы сделать следующее в raku на Windows
raku -n -e ".say if /mydatabegin/;" *.file
Не удалось открыть файл C:..*.файл: Неверный аргумент
Глобус не интерпретируется как глобус. Я предполагаю, что это потому, что Windows требует, чтобы ваши программы выполняли глобализацию самостоятельно? Итак, есть ли директива или функция предварительной обработки, или даже переключатель, который я мог пропустить, или перенаправление, или что-то, что позволяет расширить глобус, сохраняя при этом простоту переключателей-n (или-p) и-e?
Очевидно, что я могу изменить его на полную программу, удалив-n (или-p), просто используя-e, чтобы указать main, и зациклившись на результатах глобуса. Но мне действительно нравится-н.
пс. Я буквально только учу раку и был удивлен, что это не сработало из коробки. Таким образом, примеры полных программ с простым синтаксисом также работают. Но мне действительно нравится-н..
Редактировать: re @chenyf
raku -e ".say for $*ARGFILES" *.file
Та же ошибка. Похожие:
raku -e ".say for $*ARGFILES.lines" *.file
Та же ошибка.
raku -e "use IO::Glob; .say for glob('*.file')"
Сработало, как и ожидалось! Расширяющийся:
raku -e "use IO::Glob; .say for glob('*.file').lines"
Нет такого метода «строки» для вызова типа «IO::Glob»
Приблизиться — возможно, расширение этого вопроса является достаточно хорошим обходным путем. Но возвращаясь к одной строке, я пытаюсь:
raku -e "use IO::Glob; .say for glob($*ARGFILES)" test.file
Не удается разрешить глобус вызывающего абонента(IO::ArgFiles:D); ни одна из этих подписей не совпадает.
Хорошо — давайте вернемся к безопасности струн:
raku -e "use IO::Glob; .say for glob($*ARGFILES.Str)" test.file
Yes! SO..:
raku -e "use IO::Glob; .say for glob($*ARGFILES.Str).lines" test.file
No such method ‘lines’ for invocant of type ‘IO::Glob’
I clearly need to read more of the manual. But let’s retreat a little and see if my use case works:
raku -e "use IO::Glob; .say for glob($*ARGFILES.Str)" *.file
Failed to open file C:..*.file: Invalid argument
The same error I started off with. Could this just be a raku on windows error?
Edit:
raku -MIO::Glob -e "my @files = (map { glob($_).dir }, @*ARGS).flat; for @files -> $file { say $_ for $file.lines }" *file *file2 *5
У меня есть три набора файлов. Я почти могу смириться с этим решением — за исключением того, что по какой-то причине строки печатаются с «s
Есть какие-нибудь идеи по сокращению и избавлению от кавычек?
РЕДАКТИРОВАНИЕ Работы с автоматической глобализацией переменной $*ARGFILES:
raku -MIO::Glob -n -e "BEGIN { @*ARGS = (map { glob($_) }, @*ARGS).flat }; .say" *.file *.file2
Это имеет то преимущество, что все еще выглядит как оригинальный лайнер; он использует-n! Ему просто нужно было выполнить глобализацию, которая кажется ошибкой при создании $*ARGFILES.
raku -MIO::Glob -e "BEGIN { @*ARGS = (map { glob($_) }, @*ARGS).flat }; .say for $*ARGFILES.lines" *.file *.file2
Преобразование в $*ARGFILES.строки выше показывают, что $*ARGFILES динамически получает свои значения из @*ARGS.
Редактировать
наконец, оказывается, что функция glob не работает с каталогами, по крайней мере, в Windows (в документации есть пример, который просто не работает).
#Example from https://github.com/zostay/raku-IO-Glob
for glob("src/core/*.pm") -> $file { say ~$file }
#mine that doesn't work
raku -MIO::Glob -e "for glob('..*.file') -> $file { say ~$file }"
#mine that does work.
raku -MIO::Glob -e "for glob('*.file').dir('..') -> $file { say ~$file }"
#And therefore the final modification of the script above:
raku -MIO::Glob -e "BEGIN { @*ARGS = (map { glob(.IO.basename).dir(.IO.dirname) }, @*ARGS).flat }; .say for $*ARGFILES.lines" ..*.file
Комментарии:
1. возможно
$*ARGFILES
, поможет, например: andrewshitov.com/2018/12/24/…2. Отредактировал ответ, чтобы показать тестирование с помощью $*ARGFILES.
3. Кстати, спасибо ченифу за ссылку — я действительно проверил ее, и его примеры старательно избегали нескольких файлов, а тем более глобализации. Я действительно оставил вопрос в комментариях.
4. И
raku -e '$*ARGFILES.lines.say;' *.txt
то, и другое, иraku -e '.say for $*ARGFILES.lines;' *.txt
работайте в моей старой системе macOS. Первая однострочная строка возвращает каждый*.txt
файл в одной строке, а вторая однострочная строка дает линейный возврат, неотличимый отcat
(каждый возвращает пять*.txt
файлов из моего текущего каталога).5. Может быть, ошибка разрешений окна (каталога)? Или неправильно указан путь к файлу? Код
raku -ne ".say if /mydatabegin/;" *.txt
здесь работает нормально (обратите внимание на начальную.
точку).
Ответ №1:
Мое рудиментарное понимание глобализации файлов заключается в том, что оболочка обрабатывает это-и поскольку кажется, что вы находитесь в Windows, все ставки могут быть отменены. Единственным исключением может быть, если вы используете WSL
Windows-подсистему для Linux, что должно дать вам больше возможностей, подобных Unix/Linux:
https://docs.microsoft.com/en-us/windows/wsl/about
Согласно документу Microsoft, приведенному ниже, Windows имеет две встроенные оболочки, CMD.exe и Powershell (я считаю, что оболочка WSL выше необязательна):
«Обзор командной оболочки»
«Windows имеет две командные оболочки: командную оболочку и PowerShell. Каждая оболочка представляет собой программное обеспечение, которое обеспечивает прямую связь между вами и операционной системой или приложением, обеспечивая среду для автоматизации ИТ-операций».
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands
Ниже показано, что работает в довольно старой bash/MacOS
системе. С -ne
флагом командной строки (без автоматической печати) :
raku -ne 'print $_ ~ "n";'
raku -ne 'say $_ ;'
raku -ne '.say;'
С -pe
флагом командной строки (автопечатка) :
raku -pe 'print "";'
raku -pe ''
Я буквально только что распечатал содержимое пяти (5) *.txt
файлов, используя приведенные выше команды. -e
Флаг всегда завершает кластер флагов командной строки, но может быть объединен (см. -M
Флаг ниже для исключения).
Теперь, поскольку вы находитесь в Windows, вам, возможно, придется поменять ""
двойные кавычки на ''
одинарные (и наоборот!). Но, надеюсь, это поможет вам начать. [Любые дальнейшие проблемы, и вам, возможно, придется указать полный путь к вашему исполняемому Rakudo].
Если вы хотите, чтобы Raku обработал для вас перемещение по каталогу, есть dir()
команда Raku, которую можно использовать в сочетании с ее :test
наречием (параметром). Сравните ниже, когда в вышеупомянутом каталоге с пятью (5) *.txt
текстовыми файлами (удалите .elems
вызовы для печати фактического текста):
raku -e '.lines.elems.say for dir(test => / .txt $ /);'
14
16
34
1
16
против:
raku -e '.lines.elems.say for $*ARGFILES;' *.txt
81
https://docs.raku.org/routine/dir
ДОБАВЛЕНИЕ: Мой осмотр глоссария Raku P5-P6 предполагает, что разработчики намеренно исключили glob
функцию Perl5 из Perl6/Raku, выбрав вместо этого более мощную встроенную dir()
процедуру. Ссылки ниже:
https://docs.raku.org/language/5to6-perlfunc#index-entry-glob_-_perlfunc
https://docs.raku.org/routine/dir
Модуль Raku IO::Glob
не является основным (и … я никогда его не пробовал). Но если вы работаете в командной строке и хотите загрузить модуль, вы используете (например) -MIO::Glob
, за которым следует -e
, -ne
, или -pe
и т. Д. (Кроме того, нет необходимости включать use IO::Glob;
строку в ваш однострочный Raku, она уже загружена через -M
).
Смотрите однострочные примеры Raku с Txt::CSV
модулем и/или XML
модулем по ссылкам ниже:
https://unix.stackexchange.com/search?q=[csv] Раку
https://unix.stackexchange.com/search?q=[xml] Раку
Следуйте дополнительным окнам CMD.exe обсуждение/резолюция ниже:
Комментарии:
1. Довольно странный вид приведен
raku -pe 'print "";'
выше, потому что его можно легко изменить, чтобы добавить в ваши файлы номера строк:raku -pe 'print $,"t";' *.txt
ИЛИraku -pe 'print $~"t";' *.txt
2. Спасибо @jubilatious1 Во-первых, это должно быть в Windows, поэтому я все еще решаю проблему с Windows. Во-вторых, я не хочу изменять код после написания сценария / программы, поэтому я использую *.файлы.
3. Как твои «.строчки. скажем, конструкция @files » — однако она печатает скобки и кавычки. АРРР.
4. @GerardONeill Я отвечал на распространенные вопросы по обработке текста в Raku в Unix и Linux , просто выполните поиск «Raku» в поле вверху. Если иногда вы видите однострочный ответ Raku с дополнительными скобками и кавычками, удалите все звонки
.raku
и/или.perl
. Я буду время от времени включать эти звонки, чтобы визуализироватьn
новые строки и т. Д.5. К вашему сведению — .put не печатает родителей, в отличие от .скажем. Что-то о методе Str против метода gist.
Ответ №2:
Общий ответ — это не ошибка. Программы Windows должны иметь дело со своим собственным глобализацией, если они этого хотят. Для меня имеет смысл заставить его работать в исполняемом файле raku; это устраняет специфические для платформы сюрпризы и упрощает однострочные.
Но другие так не считали, и есть достаточно простое решение — создайте свой собственный модуль, чтобы код оставался последовательным и вызывался относительно просто.
Вот модуль для начала. Есть место, чтобы добавить такие вещи, как
- переключатель для обязательного успешного совпадения
- переключатель, указывающий, что сбойный глобус должен оставаться в переменной @*ARGS
- после этого переключитесь только на глобус.
- процедура для применения глобулирования вместо автоматического выполнения этого. Это позволит вам удалить переключатели, не относящиеся к файлам
- соберите каждый шарик в свой собственный список (возможно, с помощью переключателя).
Модуль:
unit module CLGlob:ver<1.0>:auth<pureabsolute>;
use IO::Glob;
@*ARGS = map { .Str }, (map { glob(.IO.basename).dir(.IO.dirname) }, @*ARGS ).flat;
Примечание: выражение во второй карте может быть упрощено, если функция glob работает для Windows с каталогами.
Примечание: Я преобразую каждый элемент в .Str, чтобы сделать @*ARGS согласованными. Файлы $*ARGFILES работали без этого, поэтому некоторая обработка может быть сохранена, если вы никогда больше не будете смотреть на @*ARGS.
Наконец, конечный результат:
raku -MCLGlob -ne ".say" ..*.file ..*.file2
Ура.
Комментарии:
1. Вы отредактировали свою операцию, чтобы указать, что пример кода для
IO::Glob
модуля не работает. Вы открыли проблему на Github в соответствующем репо?2. Нет, пока нет. Признаюсь, я и так потратил на это слишком много времени. Но в конце концов я это сделаю.