grep несколько строк из нескольких файлов и прекратить обработку других файлов, когда найдено первое совпадение - PullRequest
0 голосов
/ 29 мая 2019

У меня около 270 файлов журналов .bz2 (25 дневных журналов) и один текстовый файл с приблизительно 1500 именами пользователей. Что мне нужно сделать, это выяснить, кто из этих пользователей вошел в систему за последние 25 дней. Поэтому мне нужно извлекать имена пользователей из списка файлов и прекращать поиск, когда имя пользователя найдено в первом файле (при первом совпадении).

Мой код работает, но если в первом найденном совпадении файла мне не нужно обрабатывать другие файлы, разбивать и искать другое имя пользователя, если он найден, то есть в третьем файле, прервать и найти другое имя пользователя:

for i in $(cat /tmp/usernames.txt); do for j in $(ls *.bz2); do 
bzgrep -o -m1 $i $j; done; done

Здесь, если в первом совпадении найден файл, он ломается (флаг -m1) и начинает поиск того же имени пользователя во втором файле, но мне это больше не нужно.

Проблема: мне нужно проверять пользователей, которые не вошли в систему за последние 25 дней. Так что я могу уменьшить свои разрешения в приложении. Если пользователь вошел в систему хотя бы один раз за последние 25 дней, я не уменьшаю его разрешения.

Вопрос: мне нужно найти, кто из этих имен пользователей существует в моих файлах журнала. Если имя пользователя найдено в одном из файлов, хотя бы один раз прекратите поиск этого пользователя и начните поиск другого пользователя.

Пример: если user1 найден в file1, распечатайте его и больше не ищите этого пользователя в этом или других файлах. Если user2 найден в файле 8, распечатайте его один раз и прекратите поиск в файле 9, файле 10, файле 11 ... файле 250. Надеюсь, что это имеет смысл.

Ответы [ 3 ]

1 голос
/ 29 мая 2019

Не могли бы вы просто сделать это, чтобы получить список имен пользователей, которые появляются в любом из bzipped файлов:

bzgrep -o -w -F -f /tmp/usernames.txt *.bz2 | sort -u

, а затем сравнение этого вывода с usernames.txt, чтобы увидеть, кто вошел / не вошел в систему? Заверните его в цикл, если окажется, что более эффективно проверять один файл .bz2 за раз:

for file in *.bz2; do
    bzgrep -o -w -F -f /tmp/usernames.txt "$file"
done | sort -u

и вы можете удалить найденные имена пользователей из каждой итерации, если это тоже повысит производительность:

sort -u /tmp/usernames.txt > /tmp/names.txt
for file in *.bz2; do
    bzgrep -o -w -F -f /tmp/names.txt "$file" | sort -u > /tmp/found.txt &&
    comm -23 /tmp/names.txt /tmp/found.txt > /tmp/left.txt &&
    mv /tmp/left.txt /tmp/names.txt &&
    cat /tmp/found.txt
    [[ -s /tmp/names.txt ]] || break
done
0 голосов
/ 29 мая 2019

Если дисковое пространство не имеет значения, я бы попросил bzip2 распаковать все архивы в один файл и вызвать grep -m1 для этого файла для каждого имени пользователя:

bzcat *.bz2 > merged
while IFS='' read -r username; do
  grep -om1 "$username" merged
done < /tmp/usernames.txt
rm merged
0 голосов
/ 29 мая 2019

Вы можете использовать условное выражение:

if [ -n "$var" ]; then
     echo "Match!"
     break
fi

Эта структура означает, что условие имеет значение True только тогда, когда $ var не пусто. Цикл остановится, когда условие станет Истиной. Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...