這應該有所斬斷。
awk -F'">' -v OFS=';' '{gsub(/<record record_no = \"[0-9]+\" error_code="/,""); gsub(/"/,"\""); print $2,$1}'
的策略是:
- 在關閉xml元素的字符
">
- 除去包括屬性名稱僅留下誤差的XML元素的第一比特分割字符串碼。
- 全部替換
"
xml實體與"
。
- 以相反的順序打印兩個FS部分。
使用以下數據生成腳本進行測試。該腳本將生成帶有隨機長度記錄的500x20000行文件,其中一些文件的值爲破折號。
#!/bin/bash
recCount=0
for h in {1..500};
do
for i in {1..20000};
do
((recCount++))
error=$((RANDOM % 998 + 1))
record="<record record_no = "'"'"${recCount}"'"'" error_code="'"'"${error}"'"'">"
upperBound=$((RANDOM % 4 + 5))
for ((k=0; k<${upperBound}; k++));
do
randomVal=$((RANDOM % 99999999 + 1))
record+=""${randomVal}"
if [[ $((RANDOM % 4)) == 0 ]];
then
randomVal=$((RANDOM % 99999999 + 1))
record+="-${randomVal}"
fi
record+="""
if [[ $k != $((${upperBound} - 1)) ]];
then
record+=";"
fi
done;
echo "${record}" >> "file-${h}.txt"
done;
done;
在我的筆記本電腦上,我得到以下性能。
$ time cat file-*.txt | awk -F'">' -v OFS=';' '{gsub(/<record record_no = \"[0-9]+\" error_code="/,""); gsub(/"/,"\""); print $2,$1}' > result
real 0m18.985s
user 0m17.673s
sys 0m2.697s
作爲一個額外的好處,這裏是「等價」命令在sed: sed -e 's|\("\)|"|g' -e 's|^.*error_code="\([^>]\+\)">\(.\+\).*$|\2;\1|g'
慢得多,儘管該戰略是一致的。使用兩個表達式。首先用"
替換所有"
xml實體。最後在>
之後分組所有字符(。+)。顯示想起圖案以相反的順序\2;\1
計時統計:
$ time cat file-* | sed -e 's|\("\)|"|g' -e 's|^.*error_code="\([^>]\+\)">\(.\+\).*$|\2;\1|g' > result.sed
real 5m59.576s
user 5m56.136s
sys 0m9.850s
使用像XMLStarlet命令行XML解析器和做正確? – Kusalananda