![Как правильно выполнить конвейерную передачу find с помощью grep и cp в этом варианте использования](https://rvso.com/image/617841/%D0%9A%D0%B0%D0%BA%20%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%20%D0%B2%D1%8B%D0%BF%D0%BE%D0%BB%D0%BD%D0%B8%D1%82%D1%8C%20%D0%BA%D0%BE%D0%BD%D0%B2%D0%B5%D0%B9%D0%B5%D1%80%D0%BD%D1%83%D1%8E%20%D0%BF%D0%B5%D1%80%D0%B5%D0%B4%D0%B0%D1%87%D1%83%20find%20%D1%81%20%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E%20grep%20%D0%B8%20cp%20%D0%B2%20%D1%8D%D1%82%D0%BE%D0%BC%20%D0%B2%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82%D0%B5%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F.png)
Мне интересно рекурсивно выполнить grepping для строки в каталоге для шаблона, а затем cp'ing соответствующего файла в целевой каталог. Я думал, что могу сделать что-то вроде следующего, но это, похоже, не имеет смысла с инструментом поиска Linux:
find . -type f -exec grep -ilR "MY PATTERN" | xargs cp /dest/dir
Есть ли лучший способ сделать это? Или способ, который хотя бы работает, был бы хорошим началом.
решение1
Сделайте man xargs
и посмотрите на -I
флаг.
find . -type f -exec grep -ilR "MY PATTERN" {} \; | xargs -I % cp % /dest/dir/
Также после флага find
ожидается \;
или .+
-exec
решение2
Я не думаю, что вам нужно find. Рекурсивный grep:
grep -rl "MY PATTERN" .
решение3
xargs
считывает свой стандартный ввод и помещает их в конец команды, которая должна быть выполнена. Как вы написали, вы в конечном итоге выполните
cp /dest/dir sourcefile1 sourcefile2 sourcefile3
что совсем не то, что вам нужно.
Вы можете использовать -I
опцию, чтобы указать заполнитель для xargs
, например: xargs -I '{}' cp '{}' /dest/dir
.
Кроме того, find
он заботится о рекурсии, поэтому вам grep
не понадобится -R
.
Окончательное решение:
find . -type f -exec grep -il "MY PATTERN" '{}' + | xargs -I '{}' cp '{}' /dest/dir
решение4
Ни один из приведенных выше примеров не учитывает возможность grep
генерации -l
дублирующихся результатов (файлов с одинаковыми именами, но в разных местах), и, следовательно, перезаписывания find
хуком exec
файлов в целевом каталоге.
Попытка решить эту проблему:
$ tree foo
foo
├── bar
│ ├── baz
│ │ └── file
│ └── file
├── destdir
└── file
3 directories, 3 files
$ while read a; do mv $a foo/destdir/$(basename $a).$RANDOM; done < <(grep -rl content foo)
$ tree foo
foo
├── bar
│ └── baz
└── destdir
├── file.10171
├── file.10842
└── file.25404
3 directories, 3 files