Что расширяется до всех файлов в текущем каталоге рекурсивно?

Также обратите внимание, что код результата во втором столбце относится к свойствам файла. Например:

U   filename.1
 U  filename.2  
UU  filename.3

имя файла 1: файл был обновлен
имя файла 2: свойство или свойства на файле (такие как svn:keywords) были обновлены
имя файла 3: и файл и его свойства были обновлены

87
задан codeforester 15 June 2019 в 05:34
поделиться

3 ответа

Это будет работать в Bash 4:

ls -l {,**/}*.ext

Чтобы глобус с двойной звездочкой работал, необходимо установить параметр globstar (по умолчанию: включено):

shopt -s globstar

Из man bash :

    globstar
                  If set, the pattern ** used in a filename expansion con‐
                  text will match a files and zero or more directories and
                  subdirectories.  If the pattern is followed by a /, only
                  directories and subdirectories match.

Теперь мне интересно, могла ли когда-то быть ошибка в обработке globstar, потому что теперь используется просто ls ** / *. Ext Я получаю правильные результаты.

Тем не менее, я посмотрел на анализ kenorb, сделанный с использованием репозитория VLC, и обнаружил некоторые проблемы с этим анализом и в моем ответе непосредственно выше:

Сравнение с выходные данные команды find недопустимы, поскольку указание -типа f не включает другие типы файлов (в частности, каталоги), а перечисленные команды ls , вероятно, включают. Кроме того, одна из перечисленных команд, ls -1 {, ** /} *. * - который, похоже, основан на моем выше, выводит только имена , которые включают точку для тех файлов, которые находятся в подкаталогах. Вопрос OP и мой ответ содержат точку, так как ищутся файлы с определенным расширением.

Однако наиболее важно то, что существует особая проблема с использованием команды ls с шаблоном globstar ** . Возникает много дубликатов, поскольку Bash расширяет шаблон до всех имен файлов (и имен каталогов) в исследуемом дереве. После расширения команда ls перечисляет каждый из них и их содержимое, если они являются каталогами.

Пример:

В нашем текущем каталоге находится подкаталог A и его содержание:

A
└── AB
    └── ABC
        ├── ABC1
        ├── ABC2
        └── ABCD
            └── ABCD1

В том дереве, ** заменяется на «AA / AB A / AB / ABC A / AB / ABC / ABC1 A / AB / ABC / ABC2 A / AB / ABC / ABCD A / AB / ABC / ABCD / ABCD1» (7 записей). Если вы выполните echo ** , это будет точный результат, и каждая запись будет представлена ​​один раз. Однако , если вы выполните ls ** , он выведет список из каждой этих записей. По сути, выполняется ls A , за которым следует ls A / AB и т. Д., Поэтому A / AB отображается дважды. Кроме того, ls будет разделять выходные данные каждого подкаталога:

...
<blank line>
directory name:
content-item
content-item

Таким образом, использование wc -l подсчитывает все эти пустые строки и заголовки разделов с именами каталогов, что еще больше снижает счет.

Это еще одна причина, по которой вы не должны анализировать ls .

В результате этого дальнейшего анализа я рекомендую не использовать шаблон globstar ни при каких обстоятельствах, кроме итерации по дереву файлов следующим образом:

for entry in **
do
    something "$entry"
done

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

shopt -s globstar dotglob
diff <(echo ** | tr ' ' '\n') <(find . | sed 's|\./||' | sort)
0a1
> .

Я использовал tr , чтобы заменить пробелы на новые строки, что допустимо только здесь, так как никакие имена не включают пробелы. Я использовал sed , чтобы удалить ведущие ./ из каждой строки вывода из find . Я отсортировал вывод find , поскольку он обычно не отсортирован, а расширение глобусов в Bash уже отсортировано. Как видите, единственным выходом из diff был текущий каталог . вывод find . Когда я сделал ls ** | wc -l в выводе было почти вдвое больше строк.

104
ответ дан 24 November 2019 в 07:50
поделиться

Это распечатает все файлы в текущем каталоге и его подкаталогах, которые заканчиваются на '.ext'.

find . -name '*.ext' -print
13
ответ дан 24 November 2019 в 07:50
поделиться
$ find . -type f

Это отобразит все файлы в текущем каталоге. Затем вы можете выполнить другую команду для вывода с помощью -exec

$find . -type f -exec grep "foo" {} \;

, которая будет выполнять поиск в каждом файле с помощью поиска по строке «foo».

3
ответ дан 24 November 2019 в 07:50
поделиться