Почему *не* анализируют 'ls' (и что сделать вместо этого)?

Ваша проблема состоит в том, что Вы берете оболочку для того, каково это не: язык программирования. Оболочка перед всем интерпретатор командной строки. Сценарии оболочки являются сценариями. Это Вы реализуете логику, алгоритм Вашей проблемы в синтаксисе оболочки, затем Вы идете по неправильной дороге.

Существуют очевидные проблемы в Вашем коде как неупомянутые переменные. Но в целом, это просто чувствует себя ужасным для выполнения такого количества команд (поскольку оболочка является инструментом к командам выполнения, не языки программирования) только для нахождения пропорции символов кроме A и T в файле.

Кроме того, awk использует числа плавающие на 64 бита внутренне. Вы уверены, что Вам нужно больше точности, чем это. Если те числа должны использоваться чем-то, что имеет больше точности, чем которая, разве Вы не можете использовать это что-то, чтобы сделать все это?

Для ответа на вопрос Вы сделали бы:

$ echo 1 3 | awk -vRS= '{("echo scale=300\\;" $1 "/" $2 "|bc -l") | getline; print}'
.3333333333333333333333333333333333333333333333333333333333333333333\
33333333333333333333333333333333333333333333333333333333333333333333\
33333333333333333333333333333333333333333333333333333333333333333333\
33333333333333333333333333333333333333333333333333333333333333333333\
33333333333333333333333333333

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

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

echo 1 3 | awk 'BEGIN{print "scale=300"}{print $1"/"$2}' | bc

То время, только один awk и один bc команда.

Для меня довольно очевидно, что Вам нужен реальный язык программирования здесь (жемчуг, рубин, Python приходят на ум). Можно назвать интерпретатор для того языка программирования из сценария оболочки, но только однажды: всего одного вызова должно быть достаточно, чтобы сделать все это.

213
05.08.2019, 13:13
9 ответов

Я вовсе не убежден в этом, но давайте предположим ради аргумента, что вы можете, если готовы приложить достаточно усилий, разобрать вывод ls надежно, даже перед лицом "противника" - кого-то, кто знает написанный вами код и намеренно выбирает имена файлов, чтобы сломать его.

Даже если бы вы могли это сделать, это все равно было бы плохой идеей.

Bourne shell - не очень хороший язык. Его не следует использовать для чего-либо сложного, если только чрезвычайная переносимость не важнее любого другого фактора (например, autoconf).

Я утверждаю, что если вы столкнулись с проблемой, в которой разбор вывода ls кажется путем наименьшего сопротивления для shell-скрипта, то это верный признак того, что все, что вы делаете, слишком сложно для shell и вам следует переписать все на Perl или Python. Вот ваша последняя программа на Python:

import os, sys
for subdir, dirs, files in os.walk("."):
    for f in dirs + files:
      ino = os.lstat(os.path.join(subdir, f)).st_ino
      sys.stdout.write("%d %s %s\n" % (ino, subdir, f))

Здесь нет никаких проблем с необычными символами в именах файлов - output неоднозначен так же, как неоднозначен вывод ls, но это не имеет значения в "настоящей" программе (в отличие от демонстрационной, как эта), которая будет использовать результат os.path.join(subdir, f) напрямую.

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

import os, sys
filelist = []
for subdir, dirs, files in os.walk("."):
    for f in dirs + files:
        if f[0] == '.' or f[-1] == '~': continue
        lstat = os.lstat(os.path.join(subdir, f))
        filelist.append((f, subdir, lstat.st_ino))

filelist.sort(key = lambda x: x[0])
for f, subdir, ino in filelist: 
   sys.stdout.write("%d %s %s\n" % (ino, subdir, f))
191
27.01.2020, 19:28
[1120439]На эту ссылку много ссылок, потому что информация полностью точна, и она там уже очень долгое время.[12218]ls[1121077] заменяет непечатаемые символы на символы глобуса да, но этих символов нет в реальном имени файла. Почему это имеет значение? 2 причины:[12219]Если вы передаете это имя файла программе, то этого имени файла на самом деле не существует. Чтобы получить реальное имя файла, нужно расширить глобус.[12220]Глобус файла может соответствовать более чем одному файлу.[12221]Например:[12222]Обратите внимание, что у нас есть 2 файла, которые выглядят точно так же. Как вы собираетесь их различать, если они оба представлены как [1121082]a?b[1121083]?[12223]Автор называет это искажением имён файлов, когда ls возвращает список имён файлов, содержащих shell globs, а затем рекомендует использовать shell glob для получения списка файлов![12224]Здесь есть разница. Когда вы получаете глобус обратно, как показано на рисунке, этот глобус может соответствовать более чем одному файлу. Однако, когда вы выполняете итерацию по результатам, совпадающим с глобусом, вы получаете обратно точный файл, а не глобус.[12225]Например:[12226]Заметьте, как вывод [1121086]xxd[1121087] показывает, что [1121088]$file[1121089] содержал необработанные символы [1121090]\t[1121091] и [1121092]\n[1121093], а не [1121094]? [1121095]. [12227] Если вы используете [1121096]ls[1121097], то вместо этого вы получаете следующее:[12228] "Я все равно собираюсь выполнить итерацию, почему бы не использовать [1121098]ls[1121099]?"[12229] Ваш пример, который вы дали, на самом деле не работает. Похоже, что он работает, но это не так.[12230]Я имею в виду следующее:[12231]Я создал каталог с кучей имён файлов:[12232]Когда я запускаю ваш код, я получаю следующее:[12233]Куда делись остальные файлы?[12234]Давайте попробуем вместо этого:[12235]Теперь давайте используем реальный глобус:[12236]С bash[12237]Вышеприведенный пример был с моей обычной оболочкой, zsh. Когда я повторяю процедуру с bash, я получаю другой совершенно другой набор результатов с вашим примером:[12238]Тот же набор файлов:[12239]Радикально отличающийся набор результатов с вашим кодом:[12240]С оболочкой glob он работает отлично:[12241]Причина, по которой bash ведет себя таким образом, восходит к одному из пунктов, которые я сделал в начале ответа: "Глобус файла может совпадать с несколькими файлами".[12242]ls[1121101] возвращает один и тот же глобус ([1121102]a?b[1121103]) для нескольких файлов, поэтому каждый раз, когда мы расширяем этот глобус, мы получаем каждый файл, который с ним совпадает.[12243]Как воссоздать список файлов, которые я использовал:[12244]Шестнадцатиричный код из них - это символы UTF-8 NBSP.[1120496]
184
27.01.2020, 19:28
[1120503] Давайте попробуем немного упростить: [12247] Видите? Это уже неправильно. Есть 3 файла, но Бэш сообщает 4. Это потому, что набор [1121110]set[1121111] получает глобусы, генерируемые [1121112]ls[1121113], которые расширяются оболочкой перед передачей в набор [1121114]set[1121115]. Поэтому вы получаете:[12248]или, если хотите:[12249]Вышеуказанное было запущено на [1121116]bash 4.2.45[1121117]. [1120510]
54
27.01.2020, 19:28
[1128927] Возможно ли в некоторых случаях разобрать выходные данные [1129478]ls [1129479]? Конечно, идея извлечения списка номеров inode из каталога является хорошим примером - если вы знаете, что ваша реализация [1129480]ls[1129481] поддерживает [1129482]-q[1129483], и поэтому каждый файл будет выдавать ровно одну строку вывода, и все, что вам нужно - это номера inode, разобрать их из вывода [1129484]ls -Rai1q[1129485] - это, конечно же, возможное решение. Конечно, если бы автор раньше не видел совета типа "Никогда не разбирать вывод ls", он, наверное, не стал бы думать об именах файлов с новыми строками в них, и, наверное, оставил бы в результате "q", и код в этом краевом случае был бы слегка разбит - так что даже в тех случаях, когда анализ вывода [1129486]ls[1129487] целесообразен, этот совет все равно будет полезен. [12140] Более широкий смысл заключается в том, что когда новичок в скриптинге shell пытается выяснить (например) какой самый большой файл в каталоге, или какой самый последний измененный файл в каталоге, его первый инстинкт - разобрать вывод [1129488]ls[1129489] - понятен, потому что [1129490]ls[1129491] - это одна из первых команд, которые узнает новичок.[12141] К сожалению, этот инстинкт неверен, и этот подход нарушен. Более того, к сожалению, он слегка нарушен - в большинстве случаев он будет работать, но не работает в крайних случаях, которые, возможно, могут быть использованы кем-то, кто знает код.[12142]Новичок может подумать о [1129492]ls -s -s | sort -n | tail -n 1 | awk '{print $2}'[1129493], как о способе получить самый большой файл в каталоге. И это работает, пока у вас нет файла с пробелом в имени.[12143]OK, так как насчет [1129494]ls -s | сортировать -n | tail -n 1 | sed 's/[^ ]* *[0-9]* *//'[1129495]? Работает нормально до тех пор, пока у вас не появится файл с новой строкой в имени.[12144]Помогает ли добавление [1129496]-q[1129497] в аргументы [1129498]ls[1129499] при появлении новой строки в имени файла? Это может выглядеть так, пока у вас не будет 2 разных файла, которые содержат непечатаемый символ в одном и том же месте имени файла, и тогда вывод [1129500]ls[1129501] не позволит вам различить, какой из них был самым большим. Хуже того, для расширения "?" он, вероятно, прибегнет к shell'у [1129502]eval[1129503] - что вызовет проблемы, если он попадет в файл с именем, например, [12145] помогает ли [1129504]--quoting-style=shell[1129505] (если ваш [1129506]ls[1129507] даже поддерживает его)? Нет, до сих пор отображаются ? для непечатаемых символов, так что до сих пор непонятно, какое из множества совпадений было самым большим. [1129508]--quoting-style=literal[1129509]? Нет, то же самое. [1129510]--quoting-style=locale[1129511] или [1129512]--quoting-style=c[1129513] может помочь, если вам нужно просто однозначно распечатать имя самого большого файла, но, вероятно, нет, если после этого вам нужно что-то сделать с этим файлом - это была бы куча кода, чтобы отменить кавычки и вернуться к реальному имени файла, чтобы можно было передать его, скажем, gzip.[12146]И в конце всей этой работы, даже если то, что у него есть, безопасно и правильно для всех возможных имен файлов, это было бы нечитаемо и недоступно, и это можно было бы сделать гораздо проще, безопаснее и читабельно на питоне, перле или рубине. [12147] Или даже используя другие оболочковые инструменты - с верхушки моей головы, я думаю, что это должно сделать фокус: [12148] И должно быть по крайней мере таким же портативным, как [1129514] --quoting-стиль [1129515].[1128946]
16
27.01.2020, 19:28
[119462] Ответ прост: Особые случаи [119864]ls[119865] должны перевешивать любую возможную выгоду. Этих особых случаев можно избежать, если не разбирать вывод [119866]ls[119867].

Мантра здесь [119868]никогда не доверяйте файловой системе пользователя[119869] (эквивалент [119870]никогда не доверяйте вводу пользователя[119871]). Если есть метод, который будет работать всегда, со 100% уверенностью, то это должен быть метод, который вы предпочитаете, даже если [119872]ls[119873] делает то же самое, но с меньшей уверенностью. Я не буду вдаваться в технические подробности, так как они широко освещались в [119874]terdon[119875] и [119876]Patrick[119877]. Я знаю, что из-за рисков использования [119878]ls[119879] в важной (и, возможно, дорогой) сделке, где моя работа/представительство стоит на кону, я предпочитаю любое решение, которое не имеет степени неопределенности, если его можно избежать.

Я знаю, что некоторые люди предпочитают [119880]некоторый риск, а не определенность [119881], но [119882]я подал отчет об ошибке [119883].[119467].

41
27.01.2020, 19:28

Заявленное намерение ОП

предисловие и обоснование исходного ответа обновлено 18 мая 2015 г.

mikeserv (ОП) заявил в последнем обновлении своего вопроса: «Я считаю позором , хотя то, что я впервые задал этот вопрос, чтобы указать на источник дезинформации, , и, к сожалению, ответ, получивший наибольшее количество голосов, в значительной степени вводит в заблуждение »

. ]Ну ладно; Я чувствую, что было довольно обидно, что я потратил так много времени, пытаясь понять, как объяснить, что я имею в виду, только чтобы найти , что , когда перечитывал вопрос. Этот вопрос закончился "[порождением] обсуждения, а не ответов" и в итоге составил ~ 18 КБ текста (только для вопроса, для ясности), что было бы долго даже для сообщения в блоге.

Но StackExchange - это не ваша мыльница и не ваш блог. Однако, по сути, вы использовали его, по крайней мере, как частичку того и другого. Люди в конечном итоге тратили много времени, отвечая на ваши «важные замечания», вместо того, чтобы отвечать на реальные вопросы людей. На этом этапе я буду отмечать вопрос как не подходящий для нашего формата, учитывая, что OP прямо заявил, что это даже не предназначалось для того, чтобы быть вопросом.

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

Как правило ...

простите, пожалуйста, оставшиеся неровности; я уже потратил на это слишком много времени ... вместо того, чтобы напрямую цитировать OP (как первоначально предполагалось), я попытаюсь подвести итог и перефразировать.

[в значительной степени переработано из моего исходного ответа]
после рассмотрения, я считаю, что я ошибся -читайте акцент, сделанный OP на вопросах, на которые я отвечал; тем не менее, затронутые вопросы были , и я оставил ответы в основном нетронутыми, поскольку считаю, что они являются точными и касаются вопросов, которые, как я видел, возникали в других контекстах. по поводу советов новичкам.

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

Мое предлагаемое решение проблемы состоит в том, что примеры такого рода утверждения являются просто примерами идиомы, сформулированной несколько иначе, в которой абсолютный квантор сочетается с императивом [например, «не [никогда] X »,« [вы должны] всегда Y »,« [никогда не] Z »] для формирования утверждений, предназначенных для использования в качестве общих правил или рекомендаций, особенно когда они даются новичкам в предмете, а не как абсолютные истины, несмотря на кажущуюся форму этих утверждений.

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

И тогда эксперт, возможно, решит сделать что-то в нарушение «Правил». Но это не сделало бы их менее «Правилами».

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

Вы всегда ставите пешки в центр; в дебюте - одна фигура, один ход; замок при первой же возможности; кони перед слонами; рыцарь на ободе мрачен; и всегда следите за тем, чтобы ваш расчет был доведен до конца! (Упс, извини, устаю, это для шахматного StackExchange.)

Правила, которые должны быть нарушены?

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

  • «Вы не должны когда-либо делай X ».
  • « Никогда не делай Q! »
  • « Не делай Z ».
  • « Всегда нужно делать Y! »
  • « C, неважно что. "

Хотя эти утверждения определенно кажутся констатирующими абсолютные и вневременные правила, это не так;вместо этого это способ сформулировать общие правила [a.k.a. «руководящие принципы», «практические правила», «основы» и т. д.], что, по крайней мере, возможно, является одним из подходящих способов изложить их для начинающих, которые могут читать эти статьи. Однако только потому, что они сформулированы как абсолютные, правила, безусловно, не связывают профессионалов и экспертов [которые, вероятно, были теми, кто суммировал такие правила в первую очередь, как способ фиксировать и передавать знания, полученные при решении повторяющихся вопросы в их конкретном ремесле.]

Эти правила определенно не собираются раскрыть, как эксперт будет решать сложную или нюансированную проблему, в которой, скажем, эти правила конфликтуют друг с другом; или в которых соображения, которые изначально привели к правилу, просто не применимы. Эксперты не боятся (или не должны бояться!) Просто нарушать правила, которые, как им известно, не имеют смысла в конкретной ситуации. Эксперты постоянно сталкиваются с уравновешиванием различных рисков и проблем в своем ремесле и часто должны использовать свое суждение, чтобы выбрать нарушение такого рода правил, балансируя различные факторы и не имея возможности просто полагаться на таблицу правил, которым нужно следовать. Возьмем, к примеру, Goto : ведутся долгие и повторяющиеся споры о том, вредны ли они. (Да, никогда не используйте gotos.; D)

Модальное предложение

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

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

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

если у вас нет возможности чтобы сказать, что это руководство неверно в конкретном случае, и доказать себе, что вы правы, тогда $ {RULE}

, где, конечно, вы могли бы заменить «никогда не анализировать ls output» из $ {RULE}. :)

Ах да! Что о Parsing ls Output?

Итак, учитывая все это ...Думаю, совершенно очевидно, что это правило хорошее. Прежде всего, настоящее правило должно пониматься как идиоматическое, как объяснено выше ...

Но, кроме того, дело не только в том, что вы должны хорошо разбираться в сценариях оболочки, чтобы знать, можно ли его нарушить в некоторых случаях. частный случай. Кроме того, требуется столько же навыков, чтобы сказать, что вы ошиблись , когда пытаетесь сломать его во время тестирования! И я уверенно заявляю, что очень большая часть вероятной аудитории таких статей (дающих советы вроде «Не анализируйте вывод ls !») не могут делать эти вещи , и те, кто обладает такими навыками, скорее всего, поймут, что они выяснят это самостоятельно, и все равно проигнорируют правило.

Но ... только посмотрите на этот вопрос, и как даже люди, которые, вероятно, действительно обладают навыками, думали, что это плохой призыв делать это; и сколько усилий потратил автор вопроса, чтобы добраться до точки текущего лучшего примера! Я гарантирую вам, что в решении такой сложной проблемы 99% людей ошибутся, и это даст потенциально очень плохие результаты! Даже если выбранный метод окажется удачным; пока эта (или другая) идея парсинга ls не будет принята ИТ-специалистами / разработчиками в целом, выдержит множество испытаний (особенно проверку временем) и, наконец, не сможет перейти к «общей методике» 'статус, вполне вероятно, что многие люди могут попробовать и ошибиться ... с катастрофическими последствиями.

Итак, я повторю еще раз ...что, особенно в этом случае , , что - вот почему « никогда не анализирует ls output!» это определенно правильный способ сформулировать это.

[ОБНОВЛЕНИЕ 2014-05-18: разъяснена причина ответа (см. Выше) для ответа на комментарий OP; следующее дополнение является ответом на добавления OP к вчерашнему вопросу]

[ОБНОВЛЕНИЕ 2014 -11-10:добавлены заголовки и реорганизован / переработан контент; а также: переформатирование, переформулировка, уточнение и эм ... "краткое уточнение" ... я хотел, чтобы это было просто очисткой, хотя это превратилось в небольшую переработку. Я оставил его в плачевном состоянии, поэтому в основном пытался навести порядок. я действительно чувствовал, что важно оставить первую секцию нетронутой; так что там только два незначительных изменения: лишнее «но» удалено и «то» подчеркнуто.]

† Изначально я задумал это исключительно как пояснение к моему оригиналу; но решил внести другие дополнения после размышлений

‡ см. https://unix.stackexchange.com/tour , чтобы ознакомиться с рекомендациями по сообщениям

26
27.01.2020, 19:28

Вывод команды ls -q вообще не является глобальным объектом. Он использует ? для обозначения «Здесь есть символ, который нельзя отобразить напрямую». В глобусах используется ? для обозначения «Здесь разрешен любой символ».

У глобусов есть другие специальные символы (как минимум * и [] , а внутри пары [] их больше). Ни один из них не экранируется с помощью ls -q .

$ touch x '[x]'
$ ls -1q
[x]
x

Если вы обработаете вывод ls -1q , там есть набор глобусов и расширите их, вы не только получите x дважды, но и пропустите [x ] полностью. Как глобус, он не соответствует себе как строке.

ls -q предназначена для защиты ваших глаз и / или терминала от сумасшедших персонажей, а не для создания чего-то, что вы можете передать обратно в оболочку.

51
27.01.2020, 19:28

Причина, по которой люди говорят никогда что-то не делать, не обязательно потому, что это абсолютно точно не может быть сделано правильно. Возможно, мы сможем это сделать, но это может быть более сложным и менее эффективным как по пространству, так и по времени. Например, было бы прекрасно сказать: «Никогда не создавайте большой сервер электронной коммерции на сборке x86».

А теперь перейдем к актуальной проблеме: как вы продемонстрировали, вы можете создать решение, которое анализирует ls и дает правильный результат, поэтому проблема не в правильности.

Это сложнее? Да, но мы можем скрыть это за вспомогательной функцией.

Итак, теперь об эффективности:

Экономия места: ваше решение полагается на uniq для фильтрации дубликатов, следовательно, мы не можем генерировать результаты лениво. Таким образом, либо O (1) vs. O (n) ], либо оба имеют O (n) .

Эффективность по времени: в лучшем случае uniq использует подход хэш-карты, поэтому у нас все еще есть алгоритм O (n) в количестве добытых элементов , вероятно хотя это O (n log n) .

Теперь настоящая проблема: хотя ваш алгоритм все еще выглядит неплохо, я очень осторожно использовал элементы , полученные , а не элементы для n. Потому что это имеет большое значение. Допустим, у вас есть файл \ n \ n , в результате которого будет отображаться глобус для ?? , поэтому сопоставьте все 2-символьные файлы в листинге. Как ни странно, если у вас есть другой файл \ n \ r , который также приведет к ?? , а также вернет все 2 символьных файла ... посмотрите, к чему это? Экспоненциальное, а не линейное поведение, безусловно, квалифицируется как «худшее поведение во время выполнения». В этом разница между практическим алгоритмом и тем, о котором вы пишете статьи в теоретических журналах CS.

Все любят примеры, правда? Вот так. Создайте папку под названием «test» и используйте этот скрипт python в том же каталоге, где находится папка.

#!/usr/bin/env python3
import itertools
dir = "test/"
filename_length = 3
options = "\a\b\t\n\v\f\r"

for filename in itertools.product(options, repeat=filename_length):
        open(dir + ''.join(filename), "a").close()

Единственное, что это делает, - это генерировать все произведения длиной 3 для 7 символов. Математика средней школы подсказывает нам, что должно быть 343 файла. Что ж, это должно быть очень быстро для печати, так что давайте посмотрим:

time for f in *; do stat --format='%n' "./$f" >/dev/null; done
real    0m0.508s
user    0m0.051s
sys 0m0.480s

Теперь давайте попробуем ваше первое решение, потому что я действительно не могу заставить эту

eval set -- $(ls -1qrR ././ | tr ' ' '?' |
sed -e '\|^\(\.\{,1\}\)/\.\(/.*\):|{' -e \
        's//\1\2/;\|/$|!s|.*|&/|;h;s/.*//;b}' -e \
        '/..*/!d;G;s/\(.*\)\n\(.*\)/\2\1/' -e \
        "s/'/'\\\''/g;s/.*/'&'/;s/?/'[\"?\$IFS\"]'/g" |
uniq)

вещь здесь работать на Linux mint 16 (что, я думаю, говорит о многом. удобство использования этого метода).

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

Итак, сколько времени займет

time for f in $(ls -1q | tr " " "?") ; do stat --format='%n' "./$f" >/dev/null; done

? Ну, я действительно не знаю, проверка имен файлов 343 ^ 343 занимает некоторое время - я скажу вам после тепловой смерти Вселенной.

35
20.08.2021, 12:52

Я "не анализирую ls", потому что:

  • Имена файлов могут содержать любые символы ASCII, кроме /и NUL(0x00). lsвыводит многосимвольные -представления странных символов. Это должно быть отменено (и отменено ), прежде чем имя файла можно будет передать другой программе.

  • lsвыводитSPACE(" " ), NewLine(^J)и другие символы "управления формой" в именах файлов буквально. При последующей обработке следует соблюдать особую осторожность. Все переменные должны быть заключены в кавычки.

  • По прошествии определенного времени представление даты lsизменяется с 3 полей ("mmm dd HH:MM" )на 1 поле ("yyyy" ), и все последующие поля перенумерованы.

И, #1 причина НЕ получать информацию о файлах путем "парсинга ls" :Есть лучший способ!

Команду findможно использовать для выбора файлов, а с опцией -print0создать список имен файлов (странных и формировать неповрежденные управляющие символы ), разделенные NUL 0x00байтами.

Команда xargsс опцией " -0" потребляет список разделенных NULимен файлов и передает их (снова без изменений )в command, указанный в команде xargs. линия. commandможет быть даже сценарием bash.

Команда statпри наличии списка имен файлов может вывести любую информацию о файле в указанном вами формате.

Прочитать man find xargs stat.

Чтобы посмеяться, прочтите man lsи попробуйте понять, как можно гарантировать разборчивость

2
20.08.2021, 12:52

Теги

Похожие вопросы