Назад | Перейти на главную страницу

Как правильно найти канал с помощью grep и cp в этом случае использования

Меня интересует рекурсивный поиск строки в каталоге для шаблона, а затем 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