Dha*_*lan 8 shell perl awk sed gawk
我正在尝试使用SED脚本进行模式替换,但它无法正常工作
sample_content.txt
288Y2RZDBPX1000000001dhana
JP2F64EI1000000002d
EU9V3IXI1000000003dfg1000000001dfdfds
XATSSSSFOO4dhanaUXIBB7TF71000000004adf
10Q1W4ZEAV18LXNPSPGRTTIDHBN1000000005egw
Run Code Online (Sandbox Code Playgroud)
patterns.txt
1000000001 9000000003
1000000002 2000000001
1000000003 3000000001
1000000004 4000000001
1000000005 5000000001
Run Code Online (Sandbox Code Playgroud)
预期产出
288Y2RZDBPX9000000003dhana
JP2F64EI2000000001d
EU9V3IXI3000000001dfg9000000003dfdfds
XATSSSSFOO4dhanaUXIBB7TF74000000001adf
10Q1W4ZEAV18LXNPSPGRTTIDHBN5000000001egw
Run Code Online (Sandbox Code Playgroud)
我可以用单个SED替换像
sed 's/1000000001/1000000003/g' sample_content.txt
Run Code Online (Sandbox Code Playgroud)
注意:
文件附件链接: https ://drive.google.com/open?id = 1dVzivKMirEQU3yk9KfPM6iE7tTzVRdt_
谁能建议如何在不影响性能的情况下实现这一目标
更新于2018年2月11日
在分析了真实文件之后,我得到了一个提示,即在第30和第31位有一个等级值.这有助于我们在需要的地方和所有地方申请更换.
如果等级AB则在更换的10位数电话号码41-50和101-110
如果等级BC然后在更换的10位数电话号码,11-20,61-70和151-160
如果等级DE再更换10位数的电话号码在1-10,71-80,151-160和181-190
像这样,我看到了200个样本记录的50个独特等级.
{ grade=substr($0,110,2)} // identify grade
{
if (grade == "AB") {
print substr($0,41,10) ORS substr($0,101,10)
} else if(RT == "BC"){
print substr($0,11,10) ORS substr($0,61,10) ORS substr($0,151,10)
}
like wise 50 coiditions
}
Run Code Online (Sandbox Code Playgroud)
我可以知道,这种方法是否可取或更好的方法?
试试这个。应该很快。
$ sed -f <(printf 's/%s/%s/g\n' $(<patterns.txt)) contents.txt
Run Code Online (Sandbox Code Playgroud)
这会像波纹管那样格式化`patterns.txt 的数据,而不会实际改变patterns.txt 的真实内容:
$ printf 's/%s/%s/g\n' $(<patterns.txt)
s/1000000001/9000000003/g
s/1000000002/2000000001/g
s/1000000003/3000000001/g
s/1000000004/4000000001/g
s/1000000005/5000000001/g
Run Code Online (Sandbox Code Playgroud)
然后使用switch = read sed 命令从文件中将上述所有过程替换<(...)
为一个简单sed
的脚本
sed -f
文件
$ sed -f <(printf 's/%s/%s/g\n' $(<patterns.txt)) contents.txt
288Y2RZDBPX9000000003dhana
JP2F64EI2000000001d
EU9V3IXI3000000001dfg9000000003dfdfds
XATSSSSFOO4dhanaUXIBB7TF74000000001adf
10Q1W4ZEAV18LXNPSPGRTTIDHBN5000000001egw
Run Code Online (Sandbox Code Playgroud)
基准,以备将来参考
测试环境:
将样本文件patterns.txt
使用50,000行以及contents.txt
50,000行。
来自的所有行patterns.txt
均已加载到所有解决方案中,但仅检查的前1000行contents.txt
。
测试笔记本电脑配备了双核64位Intel(R)Celeron(R)CPU N3050 @ 2.16GHz,4 GB RAM,Debian 9 64bit Testing gnu sed 4.4
和gnu awk 4.1.4
在所有情况下,输出都将发送到新文件,以避免在屏幕上打印数据的缓慢开销。
结果:
1. RavinderSingh13 1st awk解决方案
$ time awk 'FNR==NR{a[$1]=$2;next} {for(i in a){match($0,i);val=substr($0,RSTART,RLENGTH);if(val){sub(val,a[i])}};print}' patterns.txt <(head -n 1000 contents.txt) >newcontents.txt
real 19m54.408s
user 19m44.097s
sys 0m1.981s
Run Code Online (Sandbox Code Playgroud)
2. EdMorton 1st awk解决方案
$ time awk 'NR==FNR{map[$1]=$2;next}{for (old in map) {gsub(old,map[old])}print}' patterns.txt <(head -n1000 contents.txt) >newcontents.txt
real 20m3.420s
user 19m16.559s
sys 0m2.325s
Run Code Online (Sandbox Code Playgroud)
3. sed(我的sed)解决方案
$ time sed -f <(printf 's/%s/%s/g\n' $(<patterns.txt)) <(head -n 1000 contents.txt) >newcontents.txt
real 1m1.070s
user 0m59.562s
sys 0m1.443s
Run Code Online (Sandbox Code Playgroud)
4. Cyrus sed解决方案
$ time sed -f <(sed -E 's|(.*) (.*)|s/\1/\2/|g' patterns.txt) <(head -n1000 contents.txt) >newcontents.txt
real 1m0.506s
user 0m59.871s
sys 0m1.209s
Run Code Online (Sandbox Code Playgroud)
5. RavinderSingh13第二个awk解决方案
$ time awk 'FNR==NR{a[$1]=$2;next}{for(i in a){match($0,i);val=substr($0,RSTART,RLENGTH);if(val){sub(val,a[i]);print;next}};}1' patterns.txt <(head -n 1000 contents.txt) >newcontents.txt
real 0m25.572s
user 0m25.204s
sys 0m0.040s
Run Code Online (Sandbox Code Playgroud)
对于少量的输入数据(例如1000行),awk解决方案似乎不错。这次用9000条线进行另一个测试以比较性能
6.RavinderSingh13 9000行的第二个awk解决方案
$ time awk 'FNR==NR{a[$1]=$2;next}{for(i in a){match($0,i);val=substr($0,RSTART,RLENGTH);if(val){sub(val,a[i]);print;next}};}1' patterns.txt <(head -9000 contents.txt) >newcontents.txt
real 22m25.222s
user 22m19.567s
sys 0m2.091s
Run Code Online (Sandbox Code Playgroud)
7. 9000条线的Sed解决方案
$ time sed -f <(printf 's/%s/%s/g\n' $(<patterns.txt)) <(head -9000 contents.txt) >newcontents.txt
real 9m7.443s
user 9m0.552s
sys 0m2.650s
Run Code Online (Sandbox Code Playgroud)
8. 9000条并行Seds解决方案
$ cat sedpar.sh
s=$SECONDS
sed -f <(printf 's/%s/%s/g\n' $(<patterns.txt)) <(head -3000 contents.txt) >newcontents1.txt &
sed -f <(printf 's/%s/%s/g\n' $(<patterns.txt)) <(tail +3001 contents.txt |head -3000) >newcontents2.txt &
sed -f <(printf 's/%s/%s/g\n' $(<patterns.txt)) <(tail +6001 contents.txt |head -3000) >newcontents3.txt &
wait
cat newcontents1.txt newcontents2.txt newcontents3.txt >newcontents.txt && rm -f newcontents1.txt newcontents2.txt newcontents3.txt
echo "seconds elapsed: $(($SECONDS-$s))"
$ time ./sedpar.sh
seconds elapsed: 309
real 5m16.594s
user 9m43.331s
sys 0m4.232s
Run Code Online (Sandbox Code Playgroud)
将任务拆分为更多命令(如三个并行sed)似乎可以加快处理速度。
对于那些谁愿意重复自己的PC上的基准测试,你可以下载的文件contents.txt
和patterns.txt
或者通过OP的链接或通过我的github上:
归档时间: |
|
查看次数: |
1335 次 |
最近记录: |