我需要一行命令来编译和打印日志文件中列出的所有一次性运载火箭名称。
该目录下的 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
我只会使用grep
和sort -u
:
$ grep -Po '/elv/\K[^/]+' NASA_access_log_Aug95.txt | sort -u
ATLAS_CENTAUR
DELTA
TITAN
启用-P
Perl 兼容正则表达式,让我们使用\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
对输入进行排序并删除重复项