Bash-сценарии в каталоге Maildir [дубликат]

0
26.04.2018, 15:02
2 ответа

Попросите grepсамому построить список файлов, рекурсивно из текущего каталога:

grep -r MyPattern.

Это не совсем то же самое, что и *, так как он будет искать в подкаталогах -, но для почтовых каталогов это обычно то, что вам нужно.

1
28.01.2020, 02:32

Когда оболочка выполняет внешнюю команду, длина командной строки после расширения любого шаблона подстановки имени файла, такого как *, не должна превышать определенной длины.

В вашем случае 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один раз для каждого отдельного файла в каталоге.

1
28.01.2020, 02:32

Теги

Похожие вопросы