РЕДАКТИРОВАТЬ: Согласно 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 на несколькошаблон линий, затем выполните эти 2 команды с конвейером следующим образом.
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
.