Linux 文本提取 GREP

Linux Text Extraction GREP

我是 运行 Ubuntu 服务器上的 Teamspeak 3 服务器,我想使用脚本获取当前连接的客户端。

脚本当前从 Teamspeak 服务器查询输出:

clid=1 cid=11 client_database_id=161 client_nickname=Music client_type=1|clid=3 cid=11 client_database_id=153 client_nickname=Music\sBot client_type=0|clid=5 cid=1 client_database_id=68 client_nickname=Unknown\sfrom\s127.0.0.1:52537 client_type=1|clid=12 cid=11 client_database_id=3 client_nickname=FriendlyMan client_type=0|clid=16 cid=11 client_database_id=161 client_nickname=Windows\s10\sUser client_type=0|clid=20 cid=11 client_database_id=225 client_nickname=3C2J0N47H4N client_type=0

我怎样才能从这些乱七八糟的东西中提取昵称? 更具体地说,只有包含 "client_type=0".

的那些

玩过 GREP (grep -E -o 'client_nickname=\w+'),接近我想要的。

client_nickname=Music
client_nickname=Music
client_nickname=Unknown
client_nickname=FriendlyMan
client_nickname=Windows
client_nickname=3C2J0N47H4N

期望的输出:

Music Bot,FriendlyMan,Windows 10 User,3C2J0N47H4N

我们的输入只有一行:

$ cat file
clid=1 cid=11 client_database_id=161 client_nickname=Music client_type=1|clid=3 cid=11 client_database_id=153 client_nickname=Music\sBot client_type=0|clid=5 cid=1 client_database_id=68 client_nickname=Unknown\sfrom\s127.0.0.1:52537 client_type=1|clid=12 cid=11 client_database_id=3 client_nickname=FriendlyMan client_type=0|clid=16 cid=11 client_database_id=161 client_nickname=Windows\s10\sUser client_type=0|clid=20 cid=11 client_database_id=225 client_nickname=3C2J0N47H4N client_type=0

使用 grep + sed

这里有一种方法,从 grep 开始,然后使用 sed 清理到最终格式:

$ grep -oP '(?<=client_nickname=)[^=]+(?=client_type=0)' file | sed -nE 's/\s/ /g; H;1h; ${x; s/ *\n/,/g;p}'
Music Bot,FriendlyMan,Windows 10 User,3C2J0N47H4N

使用 awk

这是另一种只使用 awk 的方法:

$ awk -F'[= ]' '/client_type=0/{gsub(/\s/, " ", ); printf (f?",":""); f=1} END{print ""}' RS='|' file
Music Bot,FriendlyMan,Windows 10 User,3C2J0N47H4N

awk 代码使用| 作为记录分隔符,awk 一次读入一条记录。每条记录都分为字段,字段分隔符可以是 space 或等号。如果记录包含文本 client_type=0,那么我们将字段 8 中出现的所有 \s 替换为 space,然后打印结果字段 8.

使用bash

#!/bin/bash
sep=
( cat file; echo "|"; ) | while read -r -d\| clid cid db name type misc
do
    [ "$type" = "client_type=0" ] || continue
    name=${name//\s/ }
    printf "%s%s" "$sep" "${name#client_nickname=}"
    sep=,
done
echo ""

这会产生输出:

Music Bot,FriendlyMan,Windows 10 User,3C2J0N47H4N