как выполнить grep-фильтр содержимого всех файлов в каталоге для «TEST», а затем переместить эти файлы в другой каталог (например, домашний)?
решение1
Вы можете объединитьгрэпинаходитьдля этой задачи:
find SOURCE -maxdepth 1 -type f -exec grep -q TEST {} \; -exec mv -i {} DEST \;
Как это работает
find SOURCE -maxdepth 1 -type f
находит все файлы (-type f
) в каталогеИСТОЧНИК.Если вы хотите включить файлы также в подкаталоги, просто удалите
-maxdepth 1
.-exec grep -q TEST {} \;
grep файлы, один за другим, на наличие строкиТЕСТ. Вот{}
файл, который в данный момент обрабатывается.Переключатель
-q
делает grep "тихим", т.е. он ничего не выводит. Утверждение-exec
будет истинным, еслигрэпуспешен, т.е. строка найдена.-exec mv -i {} DEST \;
перемещает файл, содержащий строкуТЕСТв каталогДЕСТ.Переключатель
-i
делаетмв«интерактивный», т.е. он будет запрашивать подтверждение перед перезаписью других файлов.
решение2
Еще одна альтернатива (хотя для этого потребуются некоторые специфичные расширения 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
.
решение3
$ mv TEST* /путь/к/месту/назначения
У меня работает, надеюсь, у вас тоже. В моем случае это было:
$ mv note_[5,6]* ~/документы/заметки
Что переместило note_5_math.pdf и note_6_math.pdf в каталог home/documents/notes.