问题描述
注意 文件中可能有些记录缺少名称,只有电话号码存在,反之亦然,这些记录应被视为无效记录,不应在输出中显示,甚至不应在输出中插入空白行这些记录。
样本输入:
Danish 5555551212
3456782
Bulbul 5555551213
Kaloana 5555551214
Tina 6665551215
Cj
Mayuri 6665551216
输出:
(555)5551212
(555)5551213
(555)5551214
(666)5551215
(666)5551216
MyCode:
BEGIN {FS=" ";c=0;}
{
if(NF>1)
{
s[c]=$2;
c=c+1
}
}
END{
for (i=0;i<c;i++)
{
print s[i]
}
}
这只是我所到达的1/4英里。
解决方法
能否请您尝试以下。在https://ideone.com/ZMnuIp链接中进行了书面和测试,仅显示了示例。
awk '
NF==2 && match($2,/^[0-9]{3}/){
print "(" substr($2,RSTART,RLENGTH) ")" substr($2,RSTART+RLENGTH)
}
' Input_file
说明: 检查条件NF
是否为2表示行是否有2个字段并且第2个字段以3位数字开头,然后执行以下操作。打印(然后是第二个字段的3位数的子字符串,然后打印),然后剩下的行。
使用GNU awk。如果第二列仅包含数字,请使用正则表达式(^[0-9]+$
)检查,然后打印第二列:
awk '$2~/^[0-9]+$/{print $2}' file
输出:
5555551212 5555551213 5555551214 6665551215 6665551216
使用substr格式化第二列:
awk '$2~/^[0-9]+$/{print "(" substr($2,1,3) ")" substr($2,4)}' file
输出:
(555)5551212 (555)5551213 (555)5551214 (666)5551215 (666)5551216,
这可能对您有用(GNU sed):
sed -nE 's/^\S+\s([0-9]{3})([0-9]+)$/(\1)\2/p' file
关闭隐式打印-n
。
匹配有效电话号码时,请用括号括住前3位数字并仅打印该号码。
该解决方案由一个替换命令组成,格式为s/LHS/RHS/
,其中RHS / LHS代表右侧/左侧。
LHS是与模式空间中的某些内容匹配的正则表达式,即在删除新行后将当前行放置在其中的缓冲区。
RHS是替换LHS中匹配项的地方。
/
是替换命令的定界符,通常使用/
,但它几乎可以是任何其他字符,例如#
,:
或%
正则表达式或正则表达式由^\S+\s([0-9]{3})([0-9]+)$
^
代表行首的位置,同样$
代表行首的位置。
\S
代表非空白字符,它是\s
的对偶,代表空白字符,例如空格或制表符。
+
代表一个或多个前面的字符(或组),*
几乎相同,除了代表零个或多个,?
代表可选的(零个或一个),并且{3}
正好代表3。因此x{3}
与xxx
相同。
(...)
代表一个组,其中...
可以是文字字符,字符类,组,替换,反向引用或这些的组合。以后可以在替换命令的LHS或RHS中引用该组,它们从左到右从\1
到\9
编号,因此(abc)\1\1
代表abcabcabc
[0-9]
是0
至9
的数字字符类。
因此LHS的意思是:从行的开头开始,跟随一个或多个非空格字符,然后是空格字符,然后是3位数字的分组(\1
),然后是由一个或多个数字组成的分组(\2
,然后在行的末尾。
RHS表示:文字(
,后跟第一组,即电话号码的前3位数字,接着是文字)
,后跟第二组,即电话号码的其余数字电话号码。
如果替换成功,则替换结果将打印到stdout,因为存在p
标志。由于-n
选项正在运行,这意味着将仅打印匹配的行。