Попросите grep
самому построить список файлов, рекурсивно из текущего каталога:
grep -r MyPattern.
Это не совсем то же самое, что и *
, так как он будет искать в подкаталогах -, но для почтовых каталогов это обычно то, что вам нужно.
Когда оболочка выполняет внешнюю команду, длина командной строки после расширения любого шаблона подстановки имени файла, такого как *
, не должна превышать определенной длины.
В вашем случае grep 'PATTERN' *
превращается в слишком длинную команду для выполнения оболочкой.
Во втором примере:
for i in $(`cat MyFiles`); do echo $i; done
вы пытаетесь перебрать имена файлов, хранящиеся в MyFiles
, но вы очень неправильно понимаете синтаксис.
$(`cat MyFiles`)
совпадает с
$( $(cat MyFiles) )
, что означает, что содержимое MyFiles
будет интерпретироваться как команда. Вот почему вы получаете ошибку command not found
.
Есть несколько способов исправить это.но перебирать содержимое вашего файла в цикле не очень хорошо.
Стивен дает хорошее решение в своем ответе , а другое решение, предполагая, что ваш текущий рабочий каталог — это папка Maildir,
find. -type f -exec grep 'PATTERN' {} +
Это выполнит grep
несколько раз для как можно больших пакетов файлов .
Это похоже на
printf '%s\n' * | xargs grep 'PATTERN'
, но команда find
обрабатывает имена файлов с пробелами и встроенными символами новой строки.
Команда printf
выводит одно имя файла в строке. У него нет той же проблемы, что и у grep 'PATTERN' *
, так как это, скорее всего, , встроенная -в команду , и поэтому ее не нужно выполнять в оболочке как внешнюю команду.
Ваше циклическое решение также будет работать, но вместо того, чтобы перебирать результат cat
, вы можете просто выполнить
for name in *; do
grep 'PATTERN' "$name"
done
Это предполагает, что в текущем каталоге есть только обычные файлы .
Чтобы убедиться, что вы обрабатываете только почтовые сообщения, вы можете использовать
for name in *,*; do
grep 'PATTERN' "$name" /dev/null
done
Перебирает имена, которые содержат хотя бы одну запятую. Я также добавил /dev/null
, чтобы заставить grep
выводить имена файлов, соответствующие заданному шаблону. Вы можете удалить /dev/null
и вместо этого использовать -H
с grep
, если ваш grep
поддерживает это.
Подобный цикл выполняется медленно, поскольку мы выполняем grep
один раз для каждого отдельного файла в каталоге.