Awk子串不会产生预期的结果

时间:2017-05-30 08:23:49

标签: bash shell awk scripting

我的文件内容如下:

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 number rangesnot个人IMEI numbersIMEI的常用格式为8-digits(TAC)+6-digits(Serial number)+0(padded)6 digits(Serial number)中的IMEI部分定义了开始和结束范围,其他所有部分保持不变。因此,为了在范围中找到个人IMEIs(这正是我想要的),我需要unary increment loop 6 digits(Serial number)starting IMEI number的{​​{1}}来自in Field-2 6 digits(Serial number)的{​​{1}}。我使用下面的ending IMEI number脚本:

in Field-3

它给出了以下结果:

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; 为:

expected output

我需要知道我的剧本中出了什么问题。

3 个答案:

答案 0 :(得分:1)

你的脚本的问题是你从2个字符串变量v和t开始(由于它们是字符串操作的结果,输入字符串,因为它们是字符串操作的结果,substr())然后将其转换为{{1}的数字这会剥离前导零但是你正在与v++进行字符串比较,因为字符串(t)与数字或字符串或数字字符串相比总是字符串比较。是的,您可以为每个变量添加零以强制进行数字比较,但恕我直言,这更像您正在尝试做的事情:

v <= t

当完成适当的变量时,不需要转换。另请注意,通过上述内容,您不需要重复声明相同或相对的数字来提取您关心的字符串部分,您只需说明要跳过的字符数(8)和要选择的数字( 6)一次。以上使用GNU awk为第3个arg匹配()。

答案 1 :(得分: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

答案 2 :(得分:-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,以允许它在其他增量上工作。