Оценка файла журнала с использованием скрипта sh - PullRequest
0 голосов
/ 22 ноября 2018

У меня есть файл журнала с большим количеством строк следующего формата:

IP - - [Timestamp Zone] 'Command Weblink Format' - size

Я хочу написать скрипт script.sh, который показывает количество нажатий на каждый веб-сайт.Команда

awk '{print $7}' server.log | sort -u

должна дать мне список, который помещает каждую уникальную ссылку в отдельной строке.Команда

grep 'Weblink1' server.log | wc -l

должна дать мне количество нажатий на ссылку Web1.Мне нужна команда, которая преобразует каждую строку, созданную командой Awk выше, в переменную, а затем создает цикл, который запускает команду grep для извлеченной веб-ссылки.Я мог бы использовать

while IFS='' read -r line || [[ -n "$line" ]]; do
    echo "Text read from file: $line"
done

(источник: Читать строку за строкой, присваивая значение переменной ), но я не хочу сохранять выходной файл сценария Awk в .txt file.

Я думаю, что это будет:

while IFS='' read -r line || [[ -n "$line" ]]; do
    grep '$line' server.log | wc -l | ='$variabel' |
    echo " $line was clicked $variable times "
done

Но я не очень знаком с подключением команд в цикле, так как это мой первый раз.Будет ли этот цикл работать и как мне соединить мой цикл и скрипт Awk?

1 Ответ

0 голосов
/ 22 ноября 2018

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

awk '{print $7}' server.log |
sort -u |
while IFS= read -r line; do 
  n=$(grep -c "$line" server.log)
  echo "$line" clicked $n times
done 

# you only need the read || [ -n ] idiom if the input can end with an
# unterminated partial line (is illformed); awk print output can't.
# you don't really need the IFS= and -r because the data here is URLs 
# which cannot contain whitespace and shouldn't contain backslash,
# but I left them in as good-habit-forming.

# in general variable expansions should be doublequoted
# to prevent wordsplitting and/or globbing, although in this case 
# $line is a URL which cannot contain whitespace and practically 
# cannot be a glob. $n is a number and definitely safe.

# grep -c does the count so you don't need wc -l

или, более просто,

awk '{print $7}' server.log |
sort -u |
while IFS= read -r line; do 
  echo "$line" clicked $(grep -c "$line" server.log) times
done 

Однако, если выпросто хотите получить правильные результаты, гораздо эффективнее и несколько проще сделать это за один проход в awk:

awk '{n[$7]++}
    END{for(i in n){
        print i,"clicked",n[i],"times"}}' |
sort

# or GNU awk 4+ can do the sort itself, see the doc:
awk '{n[$7]++}
    END{PROCINFO["sorted_in"]="@ind_str_asc";
    for(i in n){
        print i,"clicked",n[i],"times"}}'

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

...