Меня интересует рекурсивный поиск строки в каталоге для шаблона, а затем cp'ing соответствующего файла в целевой каталог. Я думал, что могу сделать что-то вроде следующего, но, похоже, это не имеет смысла с инструментом поиска Linux:
find . -type f -exec grep -ilR "MY PATTERN" | xargs cp /dest/dir
Есть ли лучший способ сделать это? Или способ, который даже работает, будет хорошим началом.
Делать man xargs
и посмотрите на -I
флаг.
find . -type f -exec grep -ilR "MY PATTERN" {} \; | xargs -I % cp % /dest/dir/
Также, find
ожидает \;
или +
после -exec
флаг.
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
Не думаю, что тебе нужно искать. Рекурсивный grep:
grep -rl "MY PATTERN" .
Ни один из приведенных выше примеров не учитывает возможность 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