2017-05-30 46 views
-2

我有,其内容的文件如下:在awk子犯规产量预期的结果

C2:0301,353458082243570,353458082243580,0; 
C2:0301,353458082462440,353458082462450,0; 
C2:0301,353458082069130,353458082069140,0; 
C2:0301,353458082246230,353458082246240,0; 
C2:0301,353458082559320,353458082559330,0; 
C2:0301,353458080153530,353458080153540,0; 
C2:0301,353458082462670,353458082462680,0; 
C2:0301,353458081943950,353458081943960,0; 
C2:0301,353458081719070,353458081719080,0; 
C2:0301,353458081392470,353458081392490,0; 

Field 2 and Field 3(考虑,作为分隔符),包含15 digit IMEI numberrangesnot个人IMEI numbers。通常的格式IMEI8-digits(TAC)+6-digits(Serial number)+0(padded)IMEI中的6 digits(Serial number)部分定义了开始和结束范围,其他部分保持相同。因此,为了找到范围个别IMEIs(这正是我想要的),我需要从6 digits(Serial number)ending IMEI numberin Field-3一个unary increment loopstarting IMEI numberin Field-2直到6 digits(Serial number)。我使用的是下面AWK脚本:

awk -F"," '{v = substr($2,9,6); t = substr($3,9,6); while(v <= t) printf "%s%0"6"s%s,%s\n", substr($3,1,8),v++,substr($3,15,2),$4;}' TEMP.OUT.merge_range_part1_21 

它给了我下面的结果:

353458082243570,0 
353458082243580,0 
353458082462440,0 
353458082462450,0 
353458082069130,0 
353458082069140,0 
353458082246230,0 
353458082246240,0 
353458082559320,0 
353458082559330,0 
353458080153530,0 
353458082462670,0 
353458082462680,0 
353458081943950,0 
353458081943960,0 
353458081719070,0 
353458081719080,0 
353458081392470,0 
353458081392480,0 
353458081392490,0 

将如预期除了在result以下线以上:

353458080153530,0 

result实际上来自input file的下面一行:

C2:0301,353458080153530,353458080153540,0; 

input fileexpected output为上述行是:

353458080153530,0 
    353458080153540,0 

我需要知道什么在我的脚本去错了。

+0

不仅你输入的一个案例,也是最后3行:'353458081392470,0 353458081392480,0 353458081392490,0' - 这'353458081392480,0'不应该有 – RomanPerekhrest

+0

@RomanPerekhrest这很好。基本上增量必须发生在substr($ 2,9,6)'上。在这种情况下,'139247'增加到'139249',因此我有'353458081392470,0 353458081392480,0 353458081392490,0',这正是我所期望的。我的问题是我的脚本没有处理我领先零的情况。例如,对于substr($ 2,9,6)上面的问题情况,是'015353'。它应该增加到“015354”,我应该同时拥有“353458080153530,0”和“353458080153540,0”。这没有发生 –

+0

忽略我的答案,因为它不会在while循环的第二次迭代中工作 –

回答

-1

使用IF语句来检查在相应的变量v则设置y前导零:

awk -F"," '{v = substr($2,9,6); t = substr($3,9,6); while(v <= t) { if (substr(v,1,1)=="0") { v++;y="0"v } else { v++;y=v } ;printf %s%0"6"s%s,%s\n", substr($3,1,8),y,substr($3,15,2),$4;v=y } }' TEMP.OUT.merge_range_part1_21 

确保while条件被包含在括号也是V是加在if条件。

在语句结尾处设置v = y以允许其在额外增量下工作。

+0

这是否甚至工作?它给了我很多错误。你的代码也只处理1'0'。我正在寻找任意数量的前导0的通用代码。所以基本上'substr($ 2,9,6)'总是必须是六位数。如果有'000153'到'000156'的情况,那也应该被处理 –

+0

它处理了你给出的样本数据,但没有考虑多个零。 –

0

问题出在脚本的while(v <= t)部分。我相信与leading 0s比赛没有正确发生。所以我确保在while循环中进行比较时他们是casted into int。 AWK文档说您可以使用value+0将值赋给int。所以我的while(v <= t)中的awk脚本需要更改为while(v+0 <= t+0)。所以下面的AWK脚本:

awk -F"," '{v = substr($2,9,6); t = substr($3,9,6); while(v <= t) printf "%s%0"6"s%s,%s\n", substr($3,1,8),v++,substr($3,15,2),$4;}' TEMP.OUT.merge_range_part1_21 

改为:

awk -F"," '{v = substr($2,9,6); t = substr($3,9,6); while(v+0 <= t+0) printf "%s%0"6"s%s,%s\n", substr($3,1,8),v++,substr($3,15,2),$4;}' TEMP.OUT.merge_range_part1_21 

这唯一的变化让我失败情况下的预期值。例如,这在我的input file

C2:0301,353458080153530,353458080153540,0; 

现在给我个人的IMEI号为:

353458080153530,0 
353458080153540,0 
+1

为了提高效率,而不是在每次比较变量时增加零,当你初始化变量时,你应该加上零。v = substr($ 2,9,6)+0; t = substr($ 3,9,6)+ 0',你也不应该在循环中多次调用substr()来获得每次相同的子串。为什么写'printf'..%0“6”s .. \ n“'而不是'printf'..%06s .. \ n”'? –

+0

@EdMorton感谢您的投入。我将合并这些。 –

1

与你的脚本的问题是你开始2个字符串变量,V和T(类型为自琴弦它们是字符串操作substr()的结果,然后将其转换为一个数字v++,该数字将去掉前导零,但随后您将与v <= t进行字符串比较,因为字符串(t)与数字或字符串或数字字符串始终是字符串比较。是的,你可以添加零到每个变量的强制数值比较但恕我直言这更像是你真正想要做的事:

$ cat tst.awk 
BEGIN { FS=","; re="(.{8})(.{6})(.*)" } 
{ 
    match($2,re,beg) 
    match($3,re,end) 
    for (i=beg[2]; i<=end[2]; i++) { 
     printf "%s%06d%s\n", end[1], i, end[3] 
    } 
} 

$ gawk -f tst.awk file 
353458082243570 
353458082243580 
353458082462440 
353458082462450 
353458082069130 
353458082069140 
353458082246230 
353458082246240 
353458082559320 
353458082559330 
353458080153530 
353458080153540 
353458082462670 
353458082462680 
353458081943950 
353458081943960 
353458081719070 
353458081719080 
353458081392470 
353458081392480 
353458081392490 

,并在与这样的相应的变量进行任何转换是必要的。同样需要注意的是,通过上述操作,您不需要重复说明相同或相对的数字来提取您关心的字符串部分,您只需指定要跳过的字符数(8)和要选择的数字(6)一旦。上面使用GNU awk为第三个arg匹配()。