как использовать grep и mv вместе в каталоге в оболочке?

как использовать grep и mv вместе в каталоге в оболочке?

как выполнить 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 dotglobBash перед 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.

Связанный контент