Я хотел бы найти все файлы в определенной папке, которые имеют имя файла не менее n
символов (включая расширение). Есть ли способ достичь этого с помощью find
?
Я думаю, что самый простой способ - это использовать:
find . -name "??????????*"
, где число ?
символов равно n
. Это просто, потому что это трудно забыть.
Но лучше всего использовать опцию -regex
для поиска имен файлов с n
или более символами:
find . -regextype posix-egrep -regex ".*[^/]{n}"
где n
должно быть натуральным числом (минимальная длина имени файла ).
См. man find
для получения более подробной информации.
Вы можете перебрать список файлов, возвращаемых find
, и проверить длину базового имени каждого файла:
min_fname() {
for path in $(find "$1" -type f); do
bn="${path##*/}"
if (( "${#bn}" >= $2 )); then
echo "$path"
fi
done
}
# usage: min_fname dir value
$ min_fname /tmp 5
$ min_fname /home/user 10
Эта функция использует только встроенные механизмы find
и Bash, и не соответствует регулярному выражению. , Поместите это определение функции в файл ~/.bashrc
, чтобы сделать команду min_fname
постоянной между входами в систему.
Вы можете использовать команду find
с тестом -regex
$ find /path/to/folder -regextype posix-basic -regex '.*/.\{5,\}'
или
$ find /path/to/folder -regextype posix-extended -regex '.*/.{5,}'
Обратите внимание, что -regex
является совпадением пути ], а не файл , совпадающий с - следовательно, вам нужно сопоставить и начальный .*/
, перед именем файла с 5+ символами
В качестве альтернативы, для чистого bash В качестве решения, вы можете включить расширенную глобализацию оболочки , а затем использовать шаблон !(@(?|??|???|????))
, означающий «все, что не соответствует ни одному, или двум, или трем, или четырем символам»
$ shopt -s extglob
$ ls -d /path/to/folder/!(@(?|??|???|????))
Если вы хотите чтобы включить подкаталоги, вы также можете включить опцию globstar
и добавить подстановочный знак **
, т.е.
$ shopt -s extglob globstar
$ ls -d /path/to/folder/**/!(@(?|??|???|????))
например
$ ls -d **/!(@(?|??|???|????))
abcde abcdef abcdefg subdir subdir/abcde subdir/abcdef subdir/abcdefg
, в то время как неинвертированные совпадения (файлы короче 5 символов) равны
$ ls -d **/@(?|??|???|????)
a ab abc abcd subdir/a subdir/ab subdir/abc subdir/abcd
Для последующего сброса параметров, используйте
[ 116]Подход Python:
#!/usr/bin/env python
from __future__ import print_function
import os,sys
def main():
treeroot = sys.argv[1]
base_len = int(sys.argv[2])
for dir,subdirs,files in os.walk(treeroot):
for f in files:
if len(f) >= base_len:
fullpath = os.path.abspath(os.path.join(dir,f))
print(fullpath)
if __name__ == '__main__' : main()
Использование просто:
./find_files_len.py /path/to/top_directory/ minimal_length
Например:
./find_files_len.py /etc 5
Это даст нам всем файлы с базовым именем по крайней мере 5 символов, найденных рекурсивно через /etc/
и все его подкаталоги. Обратите внимание, что полный путь файла будет распечатан к командной строке