从日志文件中捕获并汇编姓名列表

从日志文件中捕获并汇编姓名列表

我需要一行命令来编译和打印日志文件中列出的所有一次性运载火箭名称。

该目录下的 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 

答案1

我只会使用grepsort -u

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

启用-PPerl 兼容正则表达式,让我们使用\K表示“忽略到此点为止的所有内容”。 表示-o“仅显示行的匹配部分”。 然后,正则表达式表示“查找/elv/,忽略到 为止的所有内容/elv/,然后查找一个或多个非/字符([^/]+)。

答案2

你只需要:

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

/如果之前未在名为的数组中设置,则此操作将打印每个斜线的第五个字段作为字段分隔符,seen并且该行应包含elv。另请参阅awk'!a[$0]++'如何工作?这个答案在 Stack Overflow 上。

对于给定的样本,输出将是:

TITAN
DELTA
ATLAS_CENTAUR

答案3

你可以这样做:

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 列信息(您想要的信息)。请记住,这会计算用空格分隔的列。

    /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
    

答案4

您也可以sed使用sort

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

解释

  • -r使用扩展正则表达式(节省几个反斜杠)
  • -n不要打印我们不要求的行
  • \|/elv/|查找带有 的行/elv/\|开头的 表示|不使用/来分隔地址)
  • s|old|new|old用。。。来代替new
  • .*/elv/之前和包括的任何字符/elv/
  • ([^/]+)保存所有字符直到下一个/
  • .*任意数量的任意字符
  • \1参考我们保存的角色
  • p打印我们工作过的行
  • sort -u对输入进行排序并删除重复项

相关内容