LINUX.ORG.RU

fselect 0.9.1

 , , , ,


4

4

fselect — это консольная утилита для поиска файлов с помощью выражений, напоминающих SQL. В некоторых случаях может заменить традиционный find и написание развесистых скриптов с его использованием.

Преимущества:

  • возможность создания сложных запросов с помощью скобок и операторов SQL
  • использование подзапросов для поиска и сравнения результатов сразу в нескольких директориях
  • множество функций (агрегации, статистические, работа с датой и временем и т.д.), заимствованных из SQL
  • поиск внутри zip-архивов
  • поиск с учетом .gitignore
  • поиск по ширине/высоте изображений, метаданных EXIF
  • поиск по метаданным MP3-файлов
  • поддержка расширенных файловых атрибутов в Linux
  • поиск по хэшам содержимого файлов
  • интерактивный режим
  • форматирование вывода в CSV, JSON и null-terminated строки

Релиз 0.9.1 ознаменовался расширенной поддержкой подзапросов в операторах IN и EXISTS. Таким образом, теперь стало возможным искать файлы и сравнивать результаты поиска сразу в нескольких директориях.

Пример запроса (поиск файлов формата Markdown из директории content, для которых не были сгенерированы соответствующие HTML-файлы в директории public):

SELECT path
  FROM /content AS content
 WHERE NOT EXISTS (
       SELECT * FROM /public AS public
       WHERE public.dir = content.dir AND public.name = CONCAT(content.filename, '.html')) 
   AND name = '*.md'

>>> Репозиторий проекта на GitHub



Проверено: hobbit ()
Последнее исправление: hobbit (всего исправлений: 1)

поиск файлов формата Markdown из директории content, для которых не были сгенерированы соответствующие HTML-файлы в директории public

Попробовал решить эту задачу стандартными утилитами и получилось довольно многословно и развесисто. Корректность не проверял.

comm -23 \
   <{
      find content -type f |
      grep '\.md$' |
      sed 's!^[^/]*!!' |
      sort
   } \
   <{
      find public -type f |
      sed -n '/\.md\.html$/ s/.....$//p' |
      sed 's!^[^/]*!!' |
      sort
   } |
sed 's!^!content/!'
kaldeon
()
Ответ на: комментарий от kaldeon

Ии выдал такое :)

comm -23 \
  <(find content -name "*.md" | sed 's|^content/||; s|\.md$|.html|' | sort) \
  <(find public -name "*.html" | sed 's|^public/||' | sort) | \
  sed 's|\.html$|.md|'

И много других вариантов. :)))

pethead
()

Навело на мыслю, а знает ли кто о проектах ФС, устроенной внутри как реляционная БД, представляющей иноды и иерархию как view, причем представимая и как объектное хранилище с тэгами, где классическая иерархия вторична, как в BTRON.

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

lealxe
()

Не каноничная новость, где в тексте указание, что утилита написана на расте? Чо как не растоман?)

ptah_alexs ★★★★★
()
Ответ на: комментарий от ptah_alexs

Он в тегах указал, заинтересованные уже оповещены

irton ★★★★★
()

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

seiken ★★★★★
()

А если таки нужна автоматизация, проще скрипт на питоне написать. Ещё и кроссплатформенно будет, а не эти юникс-вей портянки с седами.

seiken ★★★★★
()
Последнее исправление: seiken (всего исправлений: 1)
Ответ на: комментарий от seiken

А про канонічный locate все благополучно забыли?

Не нужны для этого никакие "десктопные системы".

mord0d ★★★★★
()
Ответ на: комментарий от ptah_alexs

Он её начал писать когда ещё раст не пытались везде насильно присунуть (первая новость в 2018 году на лоре), так что выбор языка был не по фанатским причинам скорее всего.

firkax ★★★★★
()
Ответ на: комментарий от kaldeon

Не, надо модно-молодёжно:

mapfile -t md < <(basename -a content/*.md);\
mapfile -t htm < <(basename -a public/*.html);\
for f in "${md[@]}"; do
[[ ${htm[@]} == *${f%.*}* ]] || echo $f; done

🙂

papin-aziat ★★★★★
()

Это все примеры, а юзкейс-то какой? Пока все это выглядит как вещь в себе.

С поиском по содержимому неплохо gtags/global справляется, поиск по хэшам содержимого даже и не знаю кому кроме гита нужно, дубликаты файлов в разных местах редко когда нужно искать и, скорее всего, на хардлинки нарвёшься :)

gns ★★★★★
()
Ответ на: комментарий от seiken

Ну десктопные системы такое внутри себя хранят, выдавать «пользователям десктопа» такой интерфейс поиска, — так только над ними издеваться.

gns ★★★★★
()
Ответ на: комментарий от lealxe

Какое-то время назад я положил один git сервер, далее будет понятно чьей разработки, который внутри из себя представлял MSSQL кринж данных.

Всего-то надо было залить туда репозиторий на десять гигов.

a1ba ★★★
()
Ответ на: комментарий от kaldeon

Решить стандартными утилитами это воспользоваться make, вот решение от чатгпт:

# директории
CONTENT_DIR := content
PUBLIC_DIR  := public

# все markdown-файлы
MD_FILES := $(wildcard $(CONTENT_DIR)/*.md)

# соответствующие html-файлы
HTML_FILES := $(patsubst $(CONTENT_DIR)/%.md,$(PUBLIC_DIR)/%.html,$(MD_FILES))

# цель по умолчанию — сгенерировать недостающие HTML
all: $(HTML_FILES)

# правило генерации html из md
$(PUBLIC_DIR)/%.html: $(CONTENT_DIR)/%.md
	@mkdir -p $(PUBLIC_DIR)
	@echo "Generating $@ from $<"
	# 👉 здесь можно поставить свою команду:
	pandoc $< -o $@

# удобная цель для проверки
missing:
	@echo "Missing HTML files:"
	@for html in $(HTML_FILES); do \
		if [ ! -f $$html ]; then echo $$html; fi; \
	done

.PHONY: all missing

necromant ★★
()

оно реально лучше чем updatedb/locate ?

splinter ★★★★★
()
Ответ на: комментарий от necromant

Для одноразовой операции make не пишут. И в этом решении не учитываются вложенные директории.

kaldeon
()
Ответ на: комментарий от kaldeon

Слишком много вызовов sed/grep, можно проще:

find ./content -type f -name '*.md' -printf '%f\n' | sort | comm -23 - <(find ./public -type f -name '*.md.html' -exec basename -a -s .html {} + | sort) | sed 's,^,./content/,'
juan-pablo-segundo
()
Ответ на: комментарий от juan-pablo-segundo

А можете такое «ls», которое бы примерно такое:

$ superls . --with_content_details

dir1 (folders: 2, files: 222)
dir2 (folders: 0, files: 1)
dir3 (folders: 33, files: 0)
file1 (size: 1MB)
file2 (size: 111B)
?

Toxo2 ★★★★★
()
Ответ на: комментарий от Toxo2

За деньги да)

Тут уже не так просто, придется использовать awk

find . -printf '%d %y %s %p\n' | awk -f superls.awk

Значимые пробелы только в строках и после function, остальные для читаемости

function newdir(d){
    if(dir){
        printf("%s (folders: %d, files: %d)\n", dir, dirs, files)
    }
    dir=d
    dirs=0
    files=0
}
$1~0 {next}
$1~1 && $2~"d" {newdir($4)}
$1~1 && $2~"f" {
    newdir(0)
    printf("%s (size: %d)\n", $4, $3)
}
$2~"d" {dirs++}
$2~"f" {files++}
juan-pablo-segundo
()
Последнее исправление: juan-pablo-segundo (всего исправлений: 1)

AND name = ‘*.md’

Вообще по правилам SQL тут должно быть like ‘%.md’

PPP328 ★★★★★
()
Ответ на: комментарий от flant

попробовал декодировать

Там и без попыток видно, что в виде текста это мусор. Двенадцать с половиной байт как бы намекает что это что-то бинарное. (=

mord0d ★★★★★
()
Ответ на: комментарий от juan-pablo-segundo

grep в первом <{} и sed во втором можно объединить. Достоинство (хотя для кого-то недостаток) моего решения в том, что оно полностью основано на обработке текста, чего нельзя сказать даже про find: -name '*.md' применяется только к файлам.

kaldeon
()
Ответ на: комментарий от lealxe

знает ли кто о проектах ФС, устроенной внутри как реляционная БД,

Какую проблему должна решать подобная ФС?

Psilocybe ★★★★★
()
Ответ на: комментарий от Psilocybe

Не знаю. Объекты по тэгам доставать должно быть удобно. Индексы делать по желанию. Версии. Отображения.

lealxe
()
Ответ на: комментарий от PPP328

на сях пишу, ток назвал fql

Занято! :-D

https://github.com/dccmx/fql:

fql is a tool that use SQL like query to manipulate files.

fql "select time, size, name from ../"
fql "select time, size, name from abc -r"  # scan abc recursivly
fql "select * where name = fql.cc"
fql "select * where not name = fql.cc"
fql "select time, size, name from . where size > 2.5k and size < 3k order by size desc"
echo "select * from . " | fql
or run fql to query intractivly
dataman ★★★★★
()

Ура! Будущее — за алгоритмическим языком программирования Rust!

Infra_HDC ★★★★★
()
Ответ на: комментарий от PPP328

Чорт, и тут обогнали.

Если планируется создание базы файлов, как в locate/plocate, но в sqlite, то однозначно нужно!

dataman ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.