我需要从下面的输入文件中获取ErrCode,ErrAttkey和ErrDesc的grep值。 并且需要在另一个文件中显示如下
如何使用shell脚本来做到这一点?
必填输出
ErrCode|ErrAtkey|ErrDesc
003010|A3|The Unique Record IDalreadyExists
008024|A8|Prepaid / Postpaid not specified
输入文件
<TariffRecords><Tariff><UniqueID>TT07PMST0088</UniqueID><SubStat>Failure</SubStat><ErrCode>003010</ErrCode><ErrAttKey>A3</ErrAttKey><ErrDesc>The' Unique Record ID already 'Exists</ErrDesc></Tariff><Tariff><UniqueID>TT07PMST0086</UniqueID><SubStat>Success</SubStat><ErrCode>000000</ErrCode><ErrAttKey></ErrAttKey><ErrDesc>SUCCESS</ErrDesc></Tariff><Tariff><UniqueID>TT07PMCM0048</UniqueID><SubStat>Failure</SubStat><ErrCode>003010</ErrCode><ErrAttKey>A3</ErrAttKey><ErrDesc>The' Unique Record ID already 'Exists</ErrDesc></Tariff><Tariff><UniqueID>TT07PMCM0049</UniqueID><SubStat>Failure</SubStat><ErrCode>003010</ErrCode><ErrAttKey>A3</ErrAttKey><ErrDesc>The' Unique Record ID already 'Exists</ErrDesc></Tariff><Tariff><UniqueID>TT07PMPV0188</UniqueID><SubStat>Failure</SubStat><ErrCode>003010</ErrCode><ErrAttKey>A3</ErrAttKey><ErrDesc>The' Unique Record ID already 'Exists</ErrDesc></Tariff><Tariff><UniqueID>TT07PMTP0060</UniqueID><SubStat>Failure</SubStat><ErrCode>003010</ErrCode><ErrAttKey>A3</ErrAttKey><ErrDesc>The' Unique Record ID already 'Exists</ErrDesc></Tariff><Tariff><UniqueID>TT07PMVS0072</UniqueID><SubStat>Failure</SubStat><ErrCode>003010</ErrCode><ErrAttKey>A3</ErrAttKey><ErrDesc>The' Unique Record ID already 'Exists</ErrDesc></Tariff><Tariff><UniqueID>TT07PMPO0073</UniqueID><SubStat>Failure</SubStat><ErrCode>003010</ErrCode><ErrAttKey>A3</ErrAttKey><ErrDesc>The' Unique Record ID already 'Exists</ErrDesc></Tariff><Tariff><UniqueID>TT07PMPO0073</UniqueID><SubStat>Failure</SubStat><ErrCode>008024</ErrCode><ErrAttKey>A8</ErrAttKey><ErrDesc>Prepaid' / Postpaid not 'specified</ErrDesc></Tariff><Tariff><UniqueID>TT07PMSK0005</UniqueID><SubStat>Failure</SubStat><ErrCode>003010</ErrCode><ErrAttKey>A3</ErrAttKey><ErrDesc>The' Unique Record ID already 'Exists</ErrDesc></Tariff><Tariff><UniqueID>TT07PMSK0005</UniqueID><SubStat>Failure</SubStat><ErrCode>005020</ErrCode><ErrAttKey>A5</ErrAttKey><ErrDesc>Invalid' LSA 'Name</ErrDesc></Tariff><Tariff><UniqueID>TT07PMSK0005</UniqueID><SubStat>Failure</SubStat><ErrCode>008024</ErrCode><ErrAttKey>A8</ErrAttKey><ErrDesc>Prepaid' / Postpaid not 'specified</ErrDesc></Tariff><Tariff><UniqueID>TT07PMSK0005</UniqueID><SubStat>Failure</SubStat><ErrCode>015038</ErrCode><ErrAttKey>A15</ErrAttKey><ErrDesc>Regular' / Promotional is 'compulsory</ErrDesc></Tariff><Tariff><UniqueID>TT07PMSK0005</UniqueID><SubStat>Failure</SubStat><ErrCode>018048</ErrCode><ErrAttKey>A18</ErrAttKey><ErrDesc>Special' Eligibility Conditions cannot be left blank. If no conditions, please enter '`NIL`</ErrDesc></Tariff><Tariff><UniqueID>TT07PMTP0080</UniqueID><SubStat>Success</SubStat><ErrCode>000000</ErrCode><ErrAttKey></ErrAttKey><ErrDesc>SUCCESS</ErrDesc></Tariff></TariffRecords>
答案 0 :(得分:1)
假设xml的内容在文件file.txt中,则可以使用以下内容:
echo "ErrCode|ErrAtkey|ErrDesc" && cat file.txt | sed 's/<Tariff>/\n/g' | sed 's/.*<ErrCode>//g;s/<.*<ErrAttKey>/|/g;s/<.*<ErrDesc>/|/g;s/<.*//g' | grep -v '^$'
答案 1 :(得分:1)
编辑: :根据OP,即使在Input_file中多次出现所有结果,也应显示所有结果,因此在这种情况下,可能会有所帮助。
awk '{gsub(/></,">"RS"<")} 1' Input_file |
awk -F"[><]" -v time="$(date +%r)" -v date="$(date +%d/%m/%Y)" '
/ErrCode/||/ErrAttKey/||/ErrDesc/{
val=val?val OFS $3:$3
}
/<\/Tariff>/{
print val,date,time,FILENAME;
val=""
}' OFS="|"
我很惊讶您在说所有行实际上都是一行。
因此,如果您想将它们更改为多行(实际上应该是这种情况,然后在单个awk
中进行跟踪)。
awk '{gsub(/></,">"RS"<")} 1' Input_file > temp_file && mv temp_file Input_file
awk -F"[><]" '/ErrCode/{value=$3;a[value]++} a[value]==1 && NF>3 &&(/ErrCode/||/ErrAttKey/||/ErrDesc/){val=val?val OFS $3:$3} /<\/Tariff>/{if(val && val ~ /^[0-9]/){print val};val=""}' Input_file
如果您不想将Input_file更改为多行模式,请按如下所示使用管道运行这两个命令。
awk '{gsub(/></,">"RS"<")} 1' Input_file |
awk -F"[><]" '
/ErrCode/{
value=$3;
a[value]++
}
a[value]==1 && NF>3 && (/ErrCode/||/ErrAttKey/||/ErrDesc/){
val=val?val OFS $3:$3
}
/<\/Tariff>/{
if(val && val ~ /^[0-9]/){
print val};
val=""
}'
注意: 这里要注意2点,第1点:如果标签的ErrCode
值为空或不是从数字开头,则该标签的值不会被打印。第二点是它不会打印ErrCode
标签值的任何重复项。