Как удалить неотслеживаемые файлы из результатов поиска?

В zsh ** / glob означает «на любом уровне вложенности каталогов»:

grep 'interesting string' **/myfolder/myfile.out

В bash: shopt -s globstar затем как указано выше. Помните, что в bash ≤4.2 это пересекает символические ссылки на каталоги. Эта функция еще не существует в древней версии bash для OSX.

В ksh93: установите -G , затем как указано выше.

Это может привести к сбою, если общая длина имен файлов слишком велика. В этом случае вы можете вернуться к вызову find , который запустит grep в пакетном режиме:

find -path '*/myfolder/myfile.out' -exec grep -H 'interesting string' {} +

или, если вы не можете полагаться на инструменты GNU:

find -name myfolder -exec sh -c 'grep "$0" /dev/null "$1/myfile.out"' 'interesting string' {} \;

хотя, если вы Если есть zsh, то он снова приходит на помощь с zargs :

zargs -- **/myfolder/myfile.out -- grep 'interesting string' /dev/null

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

ag -G '/myfolder/myfile\.out$' 'interesting string'

1
24.05.2019, 12:34
3 ответа

А вот этот:

find. -name '*.postinst' | xargs -I something bash -c 'git ls-files | grep $(basename something)'
0
27.01.2020, 23:22

Следуя подсказке git ls-files, я создал короткий скрипт для запуска команды и фильтрации ее вывода с помощью comm. Тонкости заключаются в том, что commтребует отсортированного ввода, а строки должны быть точным текстовым соответствием (, чтобы не было префиксов, таких как ./, которые типичная команда findможет создать ).

#!/bin/bash
set -eu

usage()
{
    cat <<EOF
Usage:
   $0 cmd [args... ]

Runs _cmd_ (with arguments, if provided) and filter the output to
files currently tracked by Git.

Example:
    $0 find. -name README -mmin -60

EOF
}

trap 'usage >&2' ERR

case "${1:-}" in
    -h|--help|'-?')
        usage
        exit 0
        ;;
    '')
        usage >&2
        exit 1
        ;;
esac

exec comm -12 \
     <("$@" | xargs -d '\n' -n 1 realpath -s --relative-to=. | sort) \
     <(git ls-files | sort)
1
27.01.2020, 23:22

Если переключение на zshявляется опцией, вы можете иметь список отслеживаемых файлов в массиве:

tracked_files=(${(0)"$(git ls-files -z)"})

А затем выполните пересечение списка интересующих вас файлов, например:

postinst_files=(**/*.postinst)
tracked_postinst_files=(${postinst_files:*tracked_files})

Вы можете делать с zsh globs почти все, что можно делать с find. Например, если вы хотите, чтобы только обычные файлы были изменены за последние 2 часа:

postinst_files=(**/*.postinst(.mh-2))

Или вы можете напрямую искать свой шаблон в списке отслеживаемых файлов:

tracked_postinst_files=(${(M)tracked_files:#*.postinst})

Или определите функцию квалификатора glob, которая проверяет, находится ли файл в списке отслеживаемых файлов:

istracked() ((${tracked_files[(Ie)${1-$REPLY}]}))

tracked_postinst_files=(**/*.postinst(+istracked))
3
27.01.2020, 23:22

Теги

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