我像这样使用 awk:
grep -i 'logged in' path-to-file | tail -n -10 | awk '{ print $6, "logged in on ",substr($2,1,8),$1"."; }' | sed 's/"//g'
但在$6
列中,它是"nickname"
由用户组成的,所以有时它只有一个单词列,但有时它有多个单词。
2017-12-21 21:54:01.714540 用户 #41 昵称:“sarah the Princes” 用户名:“guest” IP 地址:111111111,UDP 地址:udp 已登录。
而不是打印整个 sarah 王子的昵称,它只显示第一个单词是 sarah。
试穿这个尺寸:
您可以使用 awk 的
gsub()
函数将所有出现的"
and"
(引号后跟空格 AND 空格后跟引号)替换为任意分隔符,并将 FS 设置为该分隔符并提取您想要的内容。请注意,如果您更改 FS,则字段编号也会更改。您还需要将 FS 重置回其原始值以正确处理下一个输入行。在您的情况下,您还希望在更改 FS之前从字段中提取一些数据(日期和时间)。
例如,如果
./file
包含 5 行,每行都是您提供的示例行的精确副本:我使用XXX作为字段分隔符,因为它不会出现在输入中的任何位置。对于此示例,制表符也可以正常工作,但这并不能证明字段分隔符不必是单个字符 - 如果您不能(或不容易),这将很重要确定输入中任何地方都没有使用的单个字符。
如果您需要从双引号字段(例如 IP 地址或 udp 端口字段)之后
gsub
提取字段数据,它会变得更加复杂 - 您不能在之前提取它们,因为您无法确定它们的字段编号是什么成为。我倾向于perl
在这一点上使用(或者甚至可能sed
像@Wildcard的回答一样),但一种方法awk
是扩展gsub
函数调用的正则表达式以适应。例如用awk
这个替换脚本:会产生这样的输出:
为了完整起见,这是
perl
使用 perl 核心模块的一种方法Text::ParseWords
:这使用
quotewords()
函数 fromText::Parsewords
将每个输入行拆分为字段(存储在名为 的数组中@F
),对某些字段进行一些小的清理,然后使用 打印所需的字段printf
。作为一个单行,它会写成:
请注意我如何更改
'/s+'
为q/\s+/
-perl 有一些很棒的引用运算符,可用于避免单引号内的单引号问题。