Получите и составьте список имен от файла журнала

Мне нужна короткая команда, чтобы скомпилировать и распечатать все Потребляемые названия Ракеты-носителя, перечисленные в файле журнала.

Имена ELV все перечислены в прописных буквах под /elv каталог.

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

ALICE
BOB
CHARLIE

Я попробовал

grep "GET" NASA_access_log_Aug95.txt | grep "ELV" | wc -l

но это только показало мне количество ELV не распечатанные имена ELV

Ниже образец моего файла журнала NASA_access_log_Aug95.txt:

cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:31 -0400] "GET /elv/TITAN/mars1s.jpg HTTP/1.0" 200 1156
www-a2.proxy.aol.com - - [03/Aug/1995:20:43:31 -0400] "GET /elv/DELTA/dsolids.jpg HTTP/1.0" 200 24558
cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:32 -0400] "GET /elv/TITAN/mars3s.jpg HTTP/1.0" 200 1744
castor.gel.usherb.ca - - [03/Aug/1995:20:43:33 -0400] "GET /shuttle/missions/51-l/movies/ HTTP/1.0" 200 372
cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:33 -0400] "GET /elv/ATLAS_CENTAUR/atc69s.jpg HTTP/1.0" 200 1659
cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:35 -0400] "GET /elv/TITAN/mars2s.jpg HTTP/1.0" 200 1549
palona1.cns.hp.com - - [03/Aug/1995:20:43:36 -0400] "GET /shuttle/missions/sts-69/count69.gif HTTP/1.0" 200 46053
www-c1.proxy.aol.com - - [03/Aug/1995:20:43:38 -0400] "GET /shuttle/missions/sts-71/images/KSC-95EC-0882.gif HTTP/1.0" 200 51289
cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:40 -0400] "GET /elv/ATLAS_CENTAUR/acsuns.jpg HTTP/1.0" 200 2263
cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:41 -0400] "GET /elv/ATLAS_CENTAUR/goess.jpg HTTP/1.0" 200 1306
cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:45 -0400] "GET /elv/DELTA/dsolidss.jpg HTTP/1.0" 200 1629 
5
задан 29 September 2018 в 05:50

5 ответов

Я просто использовал бы grep и sort -u:

$ grep -Po '/elv/\K[^/]+' NASA_access_log_Aug95.txt | sort -u
ATLAS_CENTAUR
DELTA
TITAN

-P включает Perl Совместимые Регулярные выражения, которые позволяют нам использовать \K что означает, "игнорируют что-либо подобранное до этой точки". -o означает, "только показывают часть соответствия строки". Затем средства регулярного выражения "ищут /elv/, проигнорируйте все подобранное до /elv/, и затем ищите один или несколько не -/ символы ([^/]+).

6
ответ дан 23 November 2019 в 08:38

Вам нужно просто:

awk -F'/' '/elv/ && !seen[$5]++ {print $5}' infile

Это печатает пятое поле на наклонную черту / как разделитель полей, если это ранее не установлено в названном массиве seen а также строка должна содержать elv. См. также, Как делает awk'! [0$] ++' работа? и этот ответ на Переполнении стека.

Для данного образца вывод был бы:

TITAN
DELTA
ATLAS_CENTAUR
6
ответ дан 23 November 2019 в 08:38

Можно сделать это как это:

grep 'elv' NASA_access_log_Aug95.txt | awk '{print $7}' | sed 's/[a-z0-9./]//g' | sort -u

Учитывая Ваш отрывок в качестве примера от файла журнала это произведет:

ATLAS_CENTAUR
DELTA
TITAN

Объяснение переданных по каналу команд в порядке они происходят:

  • grep 'elv' NASA_access_log_Aug95.txt

    Произведет Вас всех строки, содержащие elv

    cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:31 -0400] "GET /elv/TITAN/mars1s.jpg HTTP/1.0" 200 1156
    www-a2.proxy.aol.com - - [03/Aug/1995:20:43:31 -0400] "GET /elv/DELTA/dsolids.jpg HTTP/1.0" 200 24558
    cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:32 -0400] "GET /elv/TITAN/mars3s.jpg HTTP/1.0" 200 1744
    cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:33 -0400] "GET /elv/ATLAS_CENTAUR/atc69s.jpg HTTP/1.0" 200 1659
    cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:35 -0400] "GET /elv/TITAN/mars2s.jpg HTTP/1.0" 200 1549
    cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:40 -0400] "GET /elv/ATLAS_CENTAUR/acsuns.jpg HTTP/1.0" 200 2263
    cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:41 -0400] "GET /elv/ATLAS_CENTAUR/goess.jpg HTTP/1.0" 200 1306
    cc-rd6-mg1-dip4-9.massey.ac.nz - - [03/Aug/1995:20:43:45 -0400] "GET /elv/DELTA/dsolidss.jpg HTTP/1.0" 200 1629 
    
  • awk '{print $7}'

    Даст Вам 7-ю информацию о столбце (тот, который Вы хотите). Помните, Что это считает colums разделенным на пробелы.

    /elv/TITAN/mars1s.jpg
    /elv/DELTA/dsolids.jpg
    /elv/TITAN/mars3s.jpg
    /elv/ATLAS_CENTAUR/atc69s.jpg
    /elv/TITAN/mars2s.jpg
    /elv/ATLAS_CENTAUR/acsuns.jpg
    /elv/ATLAS_CENTAUR/goess.jpg
    /elv/DELTA/dsolidss.jpg
    
  • sed 's/[a-z0-9./]//g'

    Отфильтрует все нежелательные символы (т.е. нижний регистр a-z, числа 0-9, . и /)

    TITAN
    DELTA
    TITAN
    ATLAS_CENTAUR
    TITAN
    ATLAS_CENTAUR
    ATLAS_CENTAUR
    DELTA
    
  • sort -u

    Будет препятствовать тому, чтобы дубликаты появились, и сортирует их в алфавитном порядке.

    ATLAS_CENTAUR
    DELTA
    TITAN
    
5
ответ дан 23 November 2019 в 08:38

С Perl, regex соответствие /- разграниченные элементы после elv и продвижение их в хеш:

$ perl -lne '$h{$1}++ if m:/elv/(.*?)/: }{ for $k (sort keys %h) {print $k}' NASA_access_log_Aug95.txt 
ATLAS_CENTAUR
DELTA
TITAN
5
ответ дан 23 November 2019 в 08:38

Можно также использовать sed только с небольшой справкой от sort

$ sed -rn '\|/elv/| s|.*/elv/([^/]+).*|\1|p' NASA_access_log_Aug95.txt | sort -u
ATLAS_CENTAUR
DELTA
TITAN

Объяснение

  • -r Используйте расширенный regex (сохраняет несколько обратных косых черт),
  • -n Не печатайте строки, которые мы не просим
  • \|/elv/| найдите строки с /elv/ ( \| в запуске означает использование | нет / разграничить адрес)
  • s|old|new| замена old с new
  • .*/elv/ любые символы прежде и включая /elv/
  • ([^/]+) сохраните все символы до следующего /
  • .* любое количество любых символов
  • \1 ссылка на символы мы сохранили
  • p распечатайте строки, мы продолжили работать
  • sort -u отсортируйте вход и удалите дубликаты
5
ответ дан 23 November 2019 в 08:38

Другие вопросы по тегам:

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