Как вы grep содержимое всех файлов в каталоге для "ТЕСТ", а затем переместить эти файлы в другой каталог (например, домашний каталог)?
2 ответа
Вы можете объединить grep и найти для этой задачи:
find SOURCE -maxdepth 1 -type f -exec grep -q TEST {} \; -exec mv -i {} DEST \;
Как это устроено
find SOURCE -maxdepth 1 -type f
находит все файлы (-type f
) в каталоге SOURCE.Если вы также хотите включить файлы в подкаталоги, просто удалите
-maxdepth 1
.-exec grep -q TEST {} \;
greps файлы один за другим для строки TEST. Здесь{}
- это файл, который в данный момент обрабатывается.-q
делает grep "тихим", то есть он ничего не выводит. Оператор-exec
будет истинным, если grep успешен, то есть он находит строку.-exec mv -i {} DEST \;
перемещает файл, содержащий строку TEST, в каталог DEST.-i
делает mv "интерактивным", то есть он запрашивает перед перезаписью другие файлы.
Еще одна альтернатива (хотя для этого требуются определенные расширения GNU; поскольку вы пометили вопрос "Unix", он может не подойти вам):
grep -lZd skip TEST SOURCE/* | xargs -0I{} mv -i {} DEST
grep -l
печатает совпадающие имена файлов вместо обычного вывода.
grep -Z
дает вывод с нулевым байтовым выводом, который является безопасной ставкой при обработке странных имен файлов по каналам.
grep -d skip
определяет действие
skip
для обнаруженных каталогов среди входных аргументов.Это на самом деле не нужно; он просто избегает уведомления
grep: SOURCE/DIR: Is a directory
при обнаружении каталогов. Если вы хотите рекурсивное чтение файлов в каталогах, используйте действиеrecurse
или даже короче только эквивалентный-r
(см. Также пункт ниже).SOURCE/*
соответствует всем файлам в директории
SOURCE
с помощью оболочки подстановка. По умолчанию скрытые файлы не совпадают; это можно изменить, установивshopt -s dotglob
в Bash перед выполнением командыgrep
.Может возникнуть соблазн просто добавить
SOURCE/.*
к входным аргументам, но это может привести к неожиданным последствиям при использовании с-r
(так как мы сопоставляем.
И..
также).Если требуется рекурсивное сопоставление, просто используйте
-r SOURCE
без глобализации файла в качестве входного аргумента, который включает скрытые файлы в структуре каталогов.xargs -0
интерпретирует ввод как разделенный нулями.
xargs -I{}
определяет
{}
как заполнитель для входного аргумента.mv -i
делает движение интерактивным по предложению Денниса, чтобы избежать ошибок.
Чтобы протестировать этот шаблон (или команды в целом), полезным методом является вставка echo
перед фактической командой, чтобы увидеть, какие команды должны быть выполнены, т.е. измените mv
на echo mv
.