Почему мой bash-скрипт не перечисляет электронные письма в создаваемом им файле? - PullRequest
0 голосов
/ 03 октября 2019

Этот bash-сценарий на данный момент имеет простую предпосылку: рекурсивно просматривать каталог, извлекать каждый файл из этого каталога, и из этих файлов искать шаблоны, которые соответствуют адресам электронной почты, брать эти адреса электронной почты, сортировать их, а затем подсчитывать суммураз они появляются, и сортируйте их снова.

Возьмите эти отсортированные электронные письма и затем с помощью скрипта head напечатайте верхние электронные письма в соответствии с переменной PUNISHED.

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

вот так.

. / Myscript 20 / usr/ home / AlabasterTenRing

Вот код.

#!/bin/bash

shopt -s globstar

PUNISHED=$1
VENOM= $2

echo >> topemails.txt

for files in ./${VENOM}/**/*; do
    if [ -f "${files}" ] ; then
        <"$files" tr '[[:upper:]]' '[[:lower:]]' \
            | grep -i -o '[A-Za-z0-9._%+-]\ + @[A-Za-z0-9.]\ + .[A-Za-z]\{2,4\}' \
            | xargs -n 1 \
            | sort \
            | uniq -c \
            | sort -nr > topemails.txt
    fi
done
echo "The top \"${PUNISHED}\" emails are"
head -$PUNISHED topemails.txt

В итоге вместо этого происходит то, что topemails.txt печатает так, как задумано, но число «1» - это все, что появляется в нем.

Что я мог сделать по-другому?

Ответы [ 2 ]

1 голос
/ 03 октября 2019

Вот более простой способ воспроизвести вашу проблему:

for i in 1 2 3
do
  echo "$i" > file
done

Вы ожидаете, что file будет содержать:

1
2
3

Вместо этого оно содержит:

3

Это потому, что > усекает и перезаписывает файл каждый раз, так что вы получите результаты только после последней итерации.

Вы можете использовать каждую итерацию append вместо перезаписать :

for i in 1 2 3
do
  echo "$i" >> file
done

Или просто перенаправить весь цикл, чтобы все, что он выводит, было собрано в файле:

for i in 1 2 3
do
  echo "$i"
done > file
1 голос
/ 03 октября 2019

Что-то, что я думаю, эквивалентно вашему сценарию, но это зависит от того, какую пользу grep использует. Вы можете использовать grep для рекурсивного сканирования и пропустить цикл, так как вы все равно сканируете все файлы.

#!/bin/bash

PUNISHED=$1
VENOM=$2

echo "The top ${PUNISHED} emails are"
grep -Eroh "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}" "./${VENOM}" \
    | tr '[:upper:]' '[:lower:]' \
    | sort \
    | uniq -c \
    | sort -nr \
    | head -n $PUNISHED

Доменные имена теперь могут иметь более высокие верхние уровни, чем 4 символа, но я оставил 4 в регулярном выражении.

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