我不确定是否可以完成以下任务。我已经完成了它的第一部分,所以我在这里放了一些我想要进一步处理的代码。这个问题可能有点长,对不起。我想编辑一个如下所示的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<notes version="1">
<labels>
<label id="0" color="80FF80">BadReg</label>
<label id="1" color="FFFF40">GoodReg</label>
<label id="2" color="8000FF">Bluffer</label>
<label id="3" color="10FF10">Fish</label>
<label id="4" color="1080FF">Loose</label>
<label id="5" color="30DBFF">Semi-Loose</label>
<label id="6" color="0000FF">Nit</label>
<label id="7" color="FF9F48">Tight</label>
<label id="8" color="C0C0C0">Undefined</label>
</labels>
<note player="00aquitis00" label="7" update="1429834930"></note>
<note player="01 LUGAR" label="8" update="1429834930"></note>
<note player="07 Star 07" label="4" update="1429834930"></note>
<note player="109185" label="6" update="1429834930">Some notes are here</note>
<note player="1111167" label="8" update="1429834930">And some there...</note>
</notes>
我想在上面的* .xml文件中编辑某些玩家的ID及其标签号。首先,我有一个players.txt和一个ReportExport.csv文件,它们看起来像这样,CSV:
"","Player","VPIP","PFR","Hands","Players"
"2532|100|""Seikei""&5RS","""Seikei""&5RS","20.45","12.50","88","5.65"
"4265|100|#23Mattingly","#23Mattingly","41.94","25.81","33","5.55"
"2748|100|#PachnacyBak","#PachnacyBak","11.54","10.00","52","5.44"
"6|100|eagle189","eagle189","20.60","13.60","73,561","5.55"
TXT:
player1 badreg
player2 badreg
player3 bluffer
player4 bluffer
在第一步中,我从* .txt和* .csv文件中获取数据(我想要使用的内容)。 AWK代码:
BEGIN {
update = 1429834930 }
FILENAME == "players.txt" {
FS = "\t\t"
playertype = $2;
if (playertype == "badreg") {badregs[$1]++};
if (playertype == "bluffer") {bluffers[$1]++};
if (playertype == "fish") {fishes[$1]++};
if (playertype == "goodreg") {goodregs[$1]++};
next }
(FILENAME == "ReportExport.csv") && (FNR != 1) {
FS = "\",\""
name = $2;
vpip = $3;
pfr = $4;
hands = $5;
avgp = substr($6, 1, (length($6)-1));
if (name == "") {name = "Name"}
gsub(/&/, "\\&", name)
gsub(/</, "\\<", name)
gsub(/>/, "\\>", name)
gsub(/\"\"\"/, "\"\"", name)
gsub(/\"\"/, "\"", name)
gsub(/\"/, "\\"", name)
gsub(/,/, "", hands)
label = 8;
if ((hands >= 100) && ((vpip / 1.40) <= (100 / avgp))) {label = 7} #Tight
if ((hands >= 18) && ((vpip / 1.00) <= (100 / avgp))) {label = 7} #Tight
if ((hands >= 100) && ((vpip / 1.25) <= (100 / avgp))) {label = 6} #Nit
if ((hands >= 24) && ((vpip / 2.20) >= (100 / avgp))) {label = 5} #Semi-Loose
if ((hands >= 15) && ((vpip / 3.00) >= (100 / avgp))) {label = 4} #Loose
if ((hands >= 30) && ((vpip / 2.60) >= (100 / avgp))) {label = 4} #Loose
if ((hands >= 24) && ((vpip / 2.60) >= (100 / avgp)) && ((pfr/vpip) <= 0.2)) {label = 3} #Fish
if (name in fishes) {label = 3} #Fish
if (name in bluffers) {label = 2} #Bluffer
if (name in goodregs) {label = 1} #GoodReg
if (name in badregs) {label = 0} #BadReg
}
在此之后,当我最终为玩家获得正确的标签类型时,我想在* .xml文件中进行搜索,如果可以找到该玩家,那么我想更新他的标签数字,如果找不到,我想在其他玩家旁边打印一行到* .xml文件中,如下所示:
printf("\t<note player=\"%s\" label=\"%s\" update=\"%s\"></note>\n", name, label, update)
然后保存* .xml文件,并在处理csv文件时逐行执行此操作。在第一种情况下,如果可以找到播放器,重要的是不要替换* .xml文件中的整行,只需更新标签,因为某些播放器也可以包含一些音符(如示例代码中所示)如果我们更换整条生产线就会迷路。所以真正的问题是,这些替代品能否首先完成?如果有人能告诉我一些关于我应该继续下去的信息的话,我会感激不尽:)当然如果有更好的方法来代替保存和逐行搜索,我很想知道它。< / p>
答案 0 :(得分:1)
使用TXR的解决方案:
$ txr update.txr
<?xml version="1.0" encoding="UTF-8"?>
<notes version="1">
<labels>
<label id="0" color="80FF80">BadReg</label>
<label id="1" color="FFFF40">GoodReg</label>
<label id="2" color="8000FF">Bluffer</label>
<label id="3" color="10FF10">Fish</label>
<label id="4" color="1080FF">Loose</label>
<label id="5" color="30DBFF">Semi-Loose</label>
<label id="6" color="0000FF">Nit</label>
<label id="7" color="FF9F48">Tight</label>
<label id="8" color="C0C0C0">Undefined</label>
</labels>
<note player="00aquitis00" label="7" update="1429834930"></note>
<note player="01 LUGAR" label="8" update="1429834930"></note>
<note player="07 Star 07" label="4" update="1429834930"></note>
<note player="109185" label="7" update="1429834930">Some notes are here</note>
<note player="1111167" label="8" update="1429834930">And some there...</note>
<note player=""Seikei"&5RS" label="0" update="1429834930"></note>
<note player="#23Mattingly" label="5" update="1429834930"></note>
<note player="#PachnacyBak" label="2" update="1429834930"></note>
<note player="eagle189" label="6" update="1429834930"></note>
</notes>
update.txr
中的代码:
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@;; Lisp struct and globals ;;
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@(do
;; Structure representing a player
(defstruct player ()
name label (update g-update) notes
(vpip 0.0) (pfr 0.0) (hands 0) (avg 0.0)
;; post-construction hook
(:postinit (self)
;; calculate label based on stats, if possible
self.(calc-label)
;; If a player exists by the name, copy the properties to the old one
;; otherwise add the new one to the global list.
(iflet ((old [name2player self.name]))
old.(update-from self)
self.(add))))
;; Add new player method
(defmeth player add (self)
(push self allplayers)
(set [name2player self.name] self)
(set g-update self.update))
;; Merge new player with existing entry
(defmeth player update-from (old new)
(set old.label (or new.label old.label))
(set old.vpip (or new.vpip old.vpip))
(set old.pfr (or new.pfr old.pfr))
(set old.hands (or new.hands old.hands))
(set old.avg (or new.avg old.avg)))
;; Method to calculate player's numeric label value.
(defmeth player calc-label (p)
(if (> p.avg 0.0)
(let ((ravg (/ 100 p.avg)))
(when (and (>= p.hands 100) (<= (/ p.vpip 1.40) ravg))
(set p.label 7))
(when (and (>= p.hands 18) (<= (/ p.vpip 1.00) ravg))
(set p.label 7))
(when (and (>= p.hands 100) (<= (/ p.vpip 1.25) ravg))
(set p.label 6))
(when (and (>= p.hands 24) (>= (/ p.vpip 2.20) ravg))
(set p.label 5))
(when (and (>= p.hands 15) (>= (/ p.vpip 3.00) ravg))
(set p.label 4))
(when (and (>= p.hands 30) (>= (/ p.vpip 2.60) ravg))
(set p.label 4))
(when (and (>= p.hands 24) (>= (/ p.vpip 2.60) ravg)
(> p.vpip 0.0) (<= (/ p.pfr p.vpip) 0.2))
(set p.label 3)))))
;; Convert a player to XML.
(defmeth player toxml (p)
`<note player="@{p.name :filter :tohtml}" \
\ label="@{p.label}" update="@{p.update}">@{p.notes}</note>`)
;; Global list of all player objects
(defvarl allplayers nil)
;; Hash mapping player names to player objects.
(defvarl name2player (hash :equal-based))
;; Global variable storing most recent player update value.
(defvarl g-update)
;; Hash of lower-cased label type strings to ID strings.
(defvarl type2label (hash :equal-based)))
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@;; Process Notes.xml file ;;
@;; - instantiates player objects ;;
@;; - snarfs labels as labelxml list ;;
@;; - populates type2label hash ;;
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@(next "Notes.xml")
<?xml version="1.0" encoding="UTF-8"?>
<notes version="1">
<labels>
@(collect :gap 0 :vars (labelxml))
@ (all)
@ labelxml
@ (and)
<label id="@id" color="@co">@na</label>
@ (end)
@ (do (set [type2label (downcase-str na)] id))
@(end)
</labels>
@(repeat :gap 0)
<note player="@na" label="@l" update="@up">@nt</note>
@ (do (new player name na label l update up notes nt))
@(end)
</notes>
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@;; Process ReportExport.csv file ;;
@;; - just instantiates specified players ;;
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@(next "ReportExport.csv")
"","Player","VPIP","PFR","Hands","Players"
@(repeat :gap 0)
"@junk","@na","@vpip","@pfr","@hands","@avg"
@ (do (new player
name (regsub #/""/ "\"" na) ;; handle "" -> " in name (CSV)
vpip (tofloat vpip)
pfr (tofloat pfr)
hands (toint (remql #\, hands)) ;; nuke comma digit separator
avg (tofloat avg)))
@(end)
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@;; Process players.txt ;;
@;; - look up layer in name2player hash ;;
@;; - look up label in type2label hash ;;
@;; - if we have both, set player's label ;;
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@(next "players.txt")
@(repeat)
@name @type
@ (do (let* ((pl [name2player name])
(id [type2label (downcase-str type)]))
(when (and pl id)
(set pl.label id))))
@(end)
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@;; Output updated XML ;;
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@(bind playerxml @(mapcar (umeth toxml) (nreverse allplayers)))
@(output)
<?xml version="1.0" encoding="UTF-8"?>
<notes version="1">
<labels>
@ (repeat)
@ labelxml
@ (end)
</labels>
@ (repeat)
@playerxml
@ (end)
</notes>
@(end)
原始Notes.xml
与输出之间的差异。在这里,我们可以看到用户109185
已更新,因为该用户已添加到CSV。
$ diff -u Notes.xml <(txr update.txr)
--- Notes.xml 2015-12-21 16:04:51.790042327 -0800
+++ /dev/fd/63 2015-12-22 09:06:49.075320182 -0800
@@ -14,6 +14,10 @@
<note player="00aquitis00" label="7" update="1429834930"></note>
<note player="01 LUGAR" label="8" update="1429834930"></note>
<note player="07 Star 07" label="4" update="1429834930"></note>
- <note player="109185" label="6" update="1429834930">Some notes are here</note>
+ <note player="109185" label="7" update="1429834930">Some notes are here</note>
<note player="1111167" label="8" update="1429834930">And some there...</note>
+ <note player=""Seikei"&5RS" label="0" update="1429834930"></note>
+ <note player="#23Mattingly" label="5" update="1429834930"></note>
+ <note player="#PachnacyBak" label="2" update="1429834930"></note>
+ <note player="eagle189" label="6" update="1429834930"></note>
</notes>
player.txt
的内容。请注意,这些用户在输出中被赋予正确的标签,覆盖根据其统计数据计算的标签。
#PachnacyBak bluffer
"Seikei"&5RS badreg
ReportExport.csv
的内容:
"","Player","VPIP","PFR","Hands","Players"
"2532|100|""Seikei""&5RS","""Seikei""&5RS","20.45","12.50","88","5.65"
"4265|100|#23Mattingly","#23Mattingly","41.94","25.81","33","5.55"
"2748|100|#PachnacyBak","#PachnacyBak","11.54","10.00","52","5.44"
"6|100|eagle189","eagle189","20.60","13.60","73,561","5.55"
"blah","109185","15.60","8.60","20","4.55"