Попробуйте:
grep -rl --null --include '*.txt' LINUX/UNIX . | xargs -0r cp -t /path/to/dest
Поскольку эта команда использует NUL-разделение, она безопасна для всех имен файлов, включая имена со сложными именами, которые включают пробелы, табуляции или даже символы новой строки.
Вышеупомянутое требует GNU cp
. Для MacOS / FreeBSD попробуйте:
grep -rl --null --include '*.txt' LINUX/UNIX . | xargs -0 sh -c 'cp "$@" /path/to/dest' sh
Как это работает:
grep
параметры и аргументы
-r
предписывают grep выполнять рекурсивный поиск по структуре каталогов. (Во FreeBSD -r
будет следовать по символическим ссылкам в каталоги. Это не относится ни к OS / X, ни к последним версиям GNU grep
.)
- include '*. txt '
указывает grep возвращать только файлы, имена которых соответствуют glob *. txt
(включая скрытые, такие как .foo.txt
или .txt
) .
-l
указывает grep возвращать только имена совпадающих файлов, а не само совпадение.
- null
указывает grep использовать символы NUL для разделения имен файлов. ( - null
поддерживается grep
в GNU / Linux , MacOS и FreeBSD , но не OpenBSD .)
LINUX / UNIX
указывает grep искать только файлы, содержимое которых включает регулярное выражение LINUX / UNIX
.
поиск в текущем каталоге. Вы можете опустить его в последних версиях GNU grep
, но тогда вам нужно будет передать терминатор параметра -
в cp
для защиты от имен файлов, которые начинаются с -
.
xargs
параметры и аргументы
-0
сообщает xargs ожидать ввода, разделенного NUL.
-r
указывает xargs не запускать команду, пока не будет найден хотя бы один файл. (Эта опция не требуется ни в BSD, ни в OSX, и она несовместима с OSX xargs
.)
cp -t / path / to / dest
копирует каталоги в целевой каталог. ( -t
требует GNU cp
.)