如何读取这个结构奇怪的文本文件中的特定数据? Python
How to read specific data in this oddly structured text file? Python
我一直在为游戏《反恐精英全球攻势》开发一个 discord 机器人,在我尝试扩展它的功能时,我遇到了一些我以前从未见过的东西。我一直在寻找过去 4 个小时,但找不到任何足够接近的相关内容让我建立联系。
我在游戏中使用这个插件,它在我的服务器目录中放置了一个文本文件,我将通过 FTP 访问该文件(我很容易就把它拿下来了)。
https://github.com/splewis/get5/wiki/Stats-system
我确实有我的用户统计数据,很快就会成为存储在 json 文件中的设置,但这是我所知道的格式,每当我 运行一个命令(我会在每场比赛结束时自动用另一个插件来做)所以我无法控制改变格式。
我正在尝试做的事情:
从未知的结构化文本文件中读取特定行的数据,并在每场比赛后将其转换为字符串。
我的代码(只是读取文本文件)
with open('get5_matchstats.cfg', 'r') as file:
data = file.read()
print(data)
输出(与文本文件完全相同):
"Stats"
{
"series_type" "bo1"
"map0"
{
"team1"
{
"76561628991367478"
{
"roundsplayed" "7"
"name" "CoC Legende"
"deaths" "3"
"damage" "415"
"kills" "4"
"headshot_kills" "2"
"1kill_rounds" "4"
"firstdeath_ct" "2"
"firstkill_ct" "1"
}
"7655212110096592"
{
"roundsplayed" "7"
"name" "payperview"
"deaths" "2"
"firstdeath_ct" "1"
"damage" "672"
"kills" "6"
"1kill_rounds" "1"
"headshot_kills" "3"
"3kill_rounds" "1"
"firstkill_ct" "1"
"assists" "1"
"2kill_rounds" "1"
}
"76561198821291593"
{
"roundsplayed" "7"
"name" "dog"
"damage" "458"
"deaths" "3"
"assists" "1"
"firstdeath_ct" "1"
"firstkill_ct" "2"
"kills" "4"
"1kill_rounds" "1"
"headshot_kills" "2"
"3kill_rounds" "1"
}
"76561668131605879"
{
"roundsplayed" "7"
"name" "Cat"
"damage" "640"
"firstkill_ct" "1"
"kills" "7"
"2kill_rounds" "1"
"bomb_defuses" "1"
"1kill_rounds" "5"
"tradekill" "1"
"headshot_kills" "1"
}
"76566648819479703"
{
"roundsplayed" "7"
"name" "BackAndImBetter"
"damage" "801"
"kills" "9"
"3kill_rounds" "2"
"firstkill_ct" "1"
"headshot_kills" "3"
"assists" "1"
"2kill_rounds" "1"
"deaths" "1"
"bomb_defuses" "1"
"1kill_rounds" "1"
}
"score" "6"
}
"team2"
{
"76561198120865213"
{
"roundsplayed" "7"
"name" "Squid"
"damage" "231"
"deaths" "6"
"firstdeath_t" "2"
"kills" "1"
"headshot_kills" "1"
"1kill_rounds" "1"
}
"76561198355321210"
{
"roundsplayed" "7"
"name" "Chub vc_0"
"damage" "106"
"kills" "1"
"deaths" "6"
"1kill_rounds" "1"
"firstdeath_t" "1"
}
"76561197963353523"
{
"roundsplayed" "7"
"name" "Bravo"
"damage" "630"
"assists" "1"
"deaths" "6"
"firstdeath_t" "1"
"bomb_plants" "2"
"kills" "3"
"1kill_rounds" "1"
"firstkill_t" "1"
"2kill_rounds" "1"
}
"76561198111573735"
{
"roundsplayed" "7"
"name" "Manager"
"damage" "255"
"firstkill_t" "2"
"kills" "3"
"headshot_kills" "1"
"deaths" "6"
"2kill_rounds" "1"
"1kill_rounds" "1"
"firstdeath_t" "2"
}
"76561198853686342"
{
"roundsplayed" "7"
"name" "Compliment"
"damage" "282"
"deaths" "6"
"assists" "1"
"firstkill_t" "1"
"kills" "1"
"headshot_kills" "1"
"1kill_rounds" "1"
}
"score" "0"
}
"mapname" "de_season"
}
}
Process finished with exit code 0
在需要这些信息之前,我会得到他们的 steam64ID(一大组数字),我将使用它在他们的 discord 帐户和游戏统计数据之间创建 link。
我认为我唯一需要帮助的是弄清楚如何具体获取团队得分、用户杀戮、死亡、伤害等信息。
非常感谢你们的宝贵时间,掌握这些知识将帮助我大大改进我的机器人。
据我所知,一旦您进入地图对象(花括号),您会看到一个类似于 json 对象的模式。
只有当具有此统计信息的文件是一个小文件时,才应使用我要建议的解决方案,否则会有大量内存开销。
解决方法:读取文件,构造成一个对象,对象中有列表和字典供查询。
def convert_file_into_object(file):
team_object = {}
team_name = ""
player_id = ""
for line in file.readlines():
line = line.replace('"', '').strip()
if "{" in line:
continue
if "}" in line:
if player_id:
player_id = ""
continue
if "team" in line: # team object starts so add a new dict with team name
team_name = line
team_object[team_name] = []
continue
if line.isnumeric(): # we have hit player id, so add new player in current team
player_id = line
team_object[team_name].append({player_id: {}})
continue
player_stats = line.split()
if len(player_stats) == 2 and team_name and player_id: # we have players stats
team_object[team_name][len(team_object[team_name]) - 1][player_id][player_stats[0]] = player_stats[1]
return team_object
with open("data.txt", "r") as file:
file_object = convert_file_into_object(file)
from pprint import pprint as pp
pp(file_object)
我根据您分享的文件数据编写了这段代码。如果文件有不同的结构,则需要更改代码。
当上述代码保存在 robo.py 模块中时在 REPL 中输出。
gaurishankarbadola@ubuntu:~/python_path$ python robo.py
{'team1': [{'76561628991367478': {'1kill_rounds': '4',
'damage': '415',
'deaths': '3',
'firstdeath_ct': '2',
'firstkill_ct': '1',
'headshot_kills': '2',
'kills': '4',
'roundsplayed': '7'}},
{'7655212110096592': {'1kill_rounds': '1',
'2kill_rounds': '1',
'3kill_rounds': '1',
'assists': '1',
'damage': '672',
'deaths': '2',
'firstdeath_ct': '1',
'firstkill_ct': '1',
'headshot_kills': '3',
'kills': '6',
'name': 'payperview',
'roundsplayed': '7'}},
{'76561198821291593': {'1kill_rounds': '1',
'3kill_rounds': '1',
'assists': '1',
'damage': '458',
'deaths': '3',
'firstdeath_ct': '1',
'firstkill_ct': '2',
'headshot_kills': '2',
'kills': '4',
'name': 'dog',
'roundsplayed': '7'}},
{'76561668131605879': {'1kill_rounds': '5',
'2kill_rounds': '1',
'bomb_defuses': '1',
'damage': '640',
'firstkill_ct': '1',
'headshot_kills': '1',
'kills': '7',
'name': 'Cat',
'roundsplayed': '7',
'tradekill': '1'}},
{'76566648819479703': {'1kill_rounds': '1',
'2kill_rounds': '1',
'3kill_rounds': '2',
'assists': '1',
'bomb_defuses': '1',
'damage': '801',
'deaths': '1',
'firstkill_ct': '1',
'headshot_kills': '3',
'kills': '9',
'name': 'BackAndImBetter',
'roundsplayed': '7'}}],
'team2': [{'76561198120865213': {'1kill_rounds': '1',
'damage': '231',
'deaths': '6',
'firstdeath_t': '2',
'headshot_kills': '1',
'kills': '1',
'name': 'Squid',
'roundsplayed': '7'}},
{'76561198355321210': {'1kill_rounds': '1',
'damage': '106',
'deaths': '6',
'firstdeath_t': '1',
'kills': '1',
'roundsplayed': '7'}},
{'76561197963353523': {'1kill_rounds': '1',
'2kill_rounds': '1',
'assists': '1',
'bomb_plants': '2',
'damage': '630',
'deaths': '6',
'firstdeath_t': '1',
'firstkill_t': '1',
'kills': '3',
'name': 'Bravo',
'roundsplayed': '7'}},
{'76561198111573735': {'1kill_rounds': '1',
'2kill_rounds': '1',
'damage': '255',
'deaths': '6',
'firstdeath_t': '2',
'firstkill_t': '2',
'headshot_kills': '1',
'kills': '3',
'name': 'Manager',
'roundsplayed': '7'}},
{'76561198853686342': {'1kill_rounds': '1',
'assists': '1',
'damage': '282',
'deaths': '6',
'firstkill_t': '1',
'headshot_kills': '1',
'kills': '1',
'name': 'Compliment',
'roundsplayed': '7'}}]}
一旦你有了对象,你就可以相应地查询它。
我一直在为游戏《反恐精英全球攻势》开发一个 discord 机器人,在我尝试扩展它的功能时,我遇到了一些我以前从未见过的东西。我一直在寻找过去 4 个小时,但找不到任何足够接近的相关内容让我建立联系。 我在游戏中使用这个插件,它在我的服务器目录中放置了一个文本文件,我将通过 FTP 访问该文件(我很容易就把它拿下来了)。 https://github.com/splewis/get5/wiki/Stats-system
我确实有我的用户统计数据,很快就会成为存储在 json 文件中的设置,但这是我所知道的格式,每当我 运行一个命令(我会在每场比赛结束时自动用另一个插件来做)所以我无法控制改变格式。
我正在尝试做的事情: 从未知的结构化文本文件中读取特定行的数据,并在每场比赛后将其转换为字符串。
我的代码(只是读取文本文件)
with open('get5_matchstats.cfg', 'r') as file:
data = file.read()
print(data)
输出(与文本文件完全相同):
"Stats"
{
"series_type" "bo1"
"map0"
{
"team1"
{
"76561628991367478"
{
"roundsplayed" "7"
"name" "CoC Legende"
"deaths" "3"
"damage" "415"
"kills" "4"
"headshot_kills" "2"
"1kill_rounds" "4"
"firstdeath_ct" "2"
"firstkill_ct" "1"
}
"7655212110096592"
{
"roundsplayed" "7"
"name" "payperview"
"deaths" "2"
"firstdeath_ct" "1"
"damage" "672"
"kills" "6"
"1kill_rounds" "1"
"headshot_kills" "3"
"3kill_rounds" "1"
"firstkill_ct" "1"
"assists" "1"
"2kill_rounds" "1"
}
"76561198821291593"
{
"roundsplayed" "7"
"name" "dog"
"damage" "458"
"deaths" "3"
"assists" "1"
"firstdeath_ct" "1"
"firstkill_ct" "2"
"kills" "4"
"1kill_rounds" "1"
"headshot_kills" "2"
"3kill_rounds" "1"
}
"76561668131605879"
{
"roundsplayed" "7"
"name" "Cat"
"damage" "640"
"firstkill_ct" "1"
"kills" "7"
"2kill_rounds" "1"
"bomb_defuses" "1"
"1kill_rounds" "5"
"tradekill" "1"
"headshot_kills" "1"
}
"76566648819479703"
{
"roundsplayed" "7"
"name" "BackAndImBetter"
"damage" "801"
"kills" "9"
"3kill_rounds" "2"
"firstkill_ct" "1"
"headshot_kills" "3"
"assists" "1"
"2kill_rounds" "1"
"deaths" "1"
"bomb_defuses" "1"
"1kill_rounds" "1"
}
"score" "6"
}
"team2"
{
"76561198120865213"
{
"roundsplayed" "7"
"name" "Squid"
"damage" "231"
"deaths" "6"
"firstdeath_t" "2"
"kills" "1"
"headshot_kills" "1"
"1kill_rounds" "1"
}
"76561198355321210"
{
"roundsplayed" "7"
"name" "Chub vc_0"
"damage" "106"
"kills" "1"
"deaths" "6"
"1kill_rounds" "1"
"firstdeath_t" "1"
}
"76561197963353523"
{
"roundsplayed" "7"
"name" "Bravo"
"damage" "630"
"assists" "1"
"deaths" "6"
"firstdeath_t" "1"
"bomb_plants" "2"
"kills" "3"
"1kill_rounds" "1"
"firstkill_t" "1"
"2kill_rounds" "1"
}
"76561198111573735"
{
"roundsplayed" "7"
"name" "Manager"
"damage" "255"
"firstkill_t" "2"
"kills" "3"
"headshot_kills" "1"
"deaths" "6"
"2kill_rounds" "1"
"1kill_rounds" "1"
"firstdeath_t" "2"
}
"76561198853686342"
{
"roundsplayed" "7"
"name" "Compliment"
"damage" "282"
"deaths" "6"
"assists" "1"
"firstkill_t" "1"
"kills" "1"
"headshot_kills" "1"
"1kill_rounds" "1"
}
"score" "0"
}
"mapname" "de_season"
}
}
Process finished with exit code 0
在需要这些信息之前,我会得到他们的 steam64ID(一大组数字),我将使用它在他们的 discord 帐户和游戏统计数据之间创建 link。
我认为我唯一需要帮助的是弄清楚如何具体获取团队得分、用户杀戮、死亡、伤害等信息。
非常感谢你们的宝贵时间,掌握这些知识将帮助我大大改进我的机器人。
据我所知,一旦您进入地图对象(花括号),您会看到一个类似于 json 对象的模式。
只有当具有此统计信息的文件是一个小文件时,才应使用我要建议的解决方案,否则会有大量内存开销。
解决方法:读取文件,构造成一个对象,对象中有列表和字典供查询。
def convert_file_into_object(file):
team_object = {}
team_name = ""
player_id = ""
for line in file.readlines():
line = line.replace('"', '').strip()
if "{" in line:
continue
if "}" in line:
if player_id:
player_id = ""
continue
if "team" in line: # team object starts so add a new dict with team name
team_name = line
team_object[team_name] = []
continue
if line.isnumeric(): # we have hit player id, so add new player in current team
player_id = line
team_object[team_name].append({player_id: {}})
continue
player_stats = line.split()
if len(player_stats) == 2 and team_name and player_id: # we have players stats
team_object[team_name][len(team_object[team_name]) - 1][player_id][player_stats[0]] = player_stats[1]
return team_object
with open("data.txt", "r") as file:
file_object = convert_file_into_object(file)
from pprint import pprint as pp
pp(file_object)
我根据您分享的文件数据编写了这段代码。如果文件有不同的结构,则需要更改代码。
当上述代码保存在 robo.py 模块中时在 REPL 中输出。
gaurishankarbadola@ubuntu:~/python_path$ python robo.py
{'team1': [{'76561628991367478': {'1kill_rounds': '4',
'damage': '415',
'deaths': '3',
'firstdeath_ct': '2',
'firstkill_ct': '1',
'headshot_kills': '2',
'kills': '4',
'roundsplayed': '7'}},
{'7655212110096592': {'1kill_rounds': '1',
'2kill_rounds': '1',
'3kill_rounds': '1',
'assists': '1',
'damage': '672',
'deaths': '2',
'firstdeath_ct': '1',
'firstkill_ct': '1',
'headshot_kills': '3',
'kills': '6',
'name': 'payperview',
'roundsplayed': '7'}},
{'76561198821291593': {'1kill_rounds': '1',
'3kill_rounds': '1',
'assists': '1',
'damage': '458',
'deaths': '3',
'firstdeath_ct': '1',
'firstkill_ct': '2',
'headshot_kills': '2',
'kills': '4',
'name': 'dog',
'roundsplayed': '7'}},
{'76561668131605879': {'1kill_rounds': '5',
'2kill_rounds': '1',
'bomb_defuses': '1',
'damage': '640',
'firstkill_ct': '1',
'headshot_kills': '1',
'kills': '7',
'name': 'Cat',
'roundsplayed': '7',
'tradekill': '1'}},
{'76566648819479703': {'1kill_rounds': '1',
'2kill_rounds': '1',
'3kill_rounds': '2',
'assists': '1',
'bomb_defuses': '1',
'damage': '801',
'deaths': '1',
'firstkill_ct': '1',
'headshot_kills': '3',
'kills': '9',
'name': 'BackAndImBetter',
'roundsplayed': '7'}}],
'team2': [{'76561198120865213': {'1kill_rounds': '1',
'damage': '231',
'deaths': '6',
'firstdeath_t': '2',
'headshot_kills': '1',
'kills': '1',
'name': 'Squid',
'roundsplayed': '7'}},
{'76561198355321210': {'1kill_rounds': '1',
'damage': '106',
'deaths': '6',
'firstdeath_t': '1',
'kills': '1',
'roundsplayed': '7'}},
{'76561197963353523': {'1kill_rounds': '1',
'2kill_rounds': '1',
'assists': '1',
'bomb_plants': '2',
'damage': '630',
'deaths': '6',
'firstdeath_t': '1',
'firstkill_t': '1',
'kills': '3',
'name': 'Bravo',
'roundsplayed': '7'}},
{'76561198111573735': {'1kill_rounds': '1',
'2kill_rounds': '1',
'damage': '255',
'deaths': '6',
'firstdeath_t': '2',
'firstkill_t': '2',
'headshot_kills': '1',
'kills': '3',
'name': 'Manager',
'roundsplayed': '7'}},
{'76561198853686342': {'1kill_rounds': '1',
'assists': '1',
'damage': '282',
'deaths': '6',
'firstkill_t': '1',
'headshot_kills': '1',
'kills': '1',
'name': 'Compliment',
'roundsplayed': '7'}}]}
一旦你有了对象,你就可以相应地查询它。