|
1.背景 工作中使用MapReduce任务导出一批含有路径的文件,共计行数300W+,需要检测文件是否在对应的服务器中存在,而文件所在的服务器并非hadoop集群的服务器,因此打算采用bash脚本进行。具体的方法如下(可直接看方法2,方法1效率较低): 2. 采用的方法 a. 方法1 原本打算使用如下脚本,进行简单验证: - 8 ~* u1 |& k: u. E9 i" c( H
- !/bin/bash& E( [2 w4 m2 R2 w6 s8 z
- count=0
. U/ }$ N1 [- s- a: Q! Z - cat oriTest.txt | while read data: @$ X/ h L; W: ^( _( h
- do! `& b! [* C/ R" c8 Z; X
- count=$(( $count+1 ))
: I5 a: s2 g0 s* H - echo $count
3 D; u7 V& { r6 d$ m9 H - dir=echo "$data" | awk -F "\t" '{print $5}'" m8 q- g% B) O8 Z+ b8 c
- if [ -e $dir ];then
1 H0 h8 S# k0 W - echo "$data" >> exist.txt3 O# A, p5 r3 g2 m- O0 U+ _* ~
- else. y4 m7 j; x# R D/ v
- echo "$data" >> noexist.txt1 f/ s8 ?( O" j1 W; V( a% z
- fi
# p) K# z5 Y% t: F, }$ F! Q4 c - done
复制代码" X1 Y, |" a' ] N; Q
原始数据格式如下:
$ W$ g k' k9 A. B name mark id dir 运行时发现处理5000行需要将近4、5分钟的时间(机器为8核),果断不行啊,随后打算采用多进程的方法来执行,见方法2 b. 方法2 主要是通过将大文件分为小文件,然后对小文件进行后台遍历读取,脚本如下:
; X. r9 s8 l, K7 {0 s" X- !/bin/bash
; ?- c0 J( z$ k1 b0 g' ?5 w, L - source ~/.bashrc
复制代码
$ \+ Y5 i" d, R5 y; t8 X 判断路径是否存在
' ~) W; q- i2 _: P- readdata(){
4 o6 s+ q- [# X* x% U1 V7 k4 a - cat $1 | while read data
1 ]; \5 W* z' M- C9 R - do
' n( m% E* I& Z/ y - dir=echo "$data" | awk -F "\t" '{print $5}'0 n" x3 B) a5 Q' a8 [
- if [ -e $dir ];then$ |0 n( f/ V/ v" S3 L$ O. G7 f4 G* w
- echo "$data" >> "exist_$1.txt" o+ y6 i, M2 d, f4 A7 q0 O. \4 r
- else5 | P* n6 c9 I' t8 `
- echo "$data" >> "noexist_$1.txt"
9 R8 g' W5 u) B7 [8 y2 a- G& Y# Y - fi2 W! K; f- n5 s/ x4 P) z
- done8 q: i1 f- }# z
- }
复制代码
, H5 z* [1 S8 l& E7 k5 t/ x5 e5 j. N, K+ _0 P. ~' Z
大文件切分为小文件,生成文件名为xaa,axb等(可以自己命名文件)split -l 10000 oriTest.txt declare -a files # 声明数组 files=($(ls x*)) # 分割后的小文件名保存数组 遍历,并后台执行% p. l ?* e) d9 D
7 w9 Y) j) h5 \. K0 }- for i in ${files[@]};do! v2 i5 r2 ~) F c
- echo $i0 }& Q$ a6 U7 \! N, G8 M, U
- readdata $i &% \- ?1 E5 K' \ j/ r/ v. x
- done
复制代码
% B# w: n1 E7 f5 Z
9 b* q5 W- ~$ a% s |* H5 f0 e |