我尝试写一个小脚本(最好用bash,但python或perl也可以)来屏蔽SSN的前5位数字(格式为123 a 45 a 6789或123-45-6789 -所以它将分别输出XXXXX 6789或XXX-XX-6789)。
我知道我应该可以用sed来完成这个任务,但是我在创建正确的正则表达式时遇到了麻烦(然后我必须进行替换)。
123456789 needs to be matched.
123-45-6789 does, too.
Mask this 123-45-6789 SSN please
Don't miss 123456789 either.
123456789 should match.
123-45-6789 should also match.
As should 123456789
And 123-45-6789
But not 1234567890
1234567890 should also not match.
And 1234567890 is right out.
因此,SSN可以出现在一行的开头、中间某处或结尾。
输出(例如,前两行)应屏蔽前5个数字,例如使用X):
XXXXX6789 needs to be matched.
XXX-XX-6789 does, too.
我已经设法得到了一个grep正则表达式,它只正确地匹配我想要的表达式:
grep '\b[0-9]\{3\}-\{0,1\}[0-9]\{2\}-\{0,1\}[0-9]\{4\}\b' testfile
我想我应该能够在sed或awk中使用分组来获得我想要的结果,但是我尝试过的所有方法都不起作用。
5条答案
按热度按时间hfyxw5xn1#
使用
sed
ws51t4hk2#
用GNU awk为第三个参数到
match()
和gensub()
以及\<
和\>
的字边界:h4cxqtbf3#
您只需要捕获将在输出中结束的内容:(可能的)破折号和最后四位数字。而且,Perl的正则表达式语法消除了不必要的反斜杠,这很好。
(具体来说,在perlregex中,“magic”函数总是附加在 * 没有 * 反斜杠的标点符号上,或者附加在 * 有 * 反斜杠的字母数字上;反斜杠标点符号将始终使其不特殊。)
x9ybnkn64#
假设前8行应用了遮罩(最后3行保持不变):
修改输入文件以在前2行中包括双重匹配的SSN模式:
一个
sed
想法使用OP的regex的修改版本:其中:
-r
-启用扩展的正则表达式支持(无需转义圆括号和大括号)([0-9]{3})
-匹配3位数字(* 第1个捕获组 *)(-{0,1})
-匹配可选的-
(* 第二个捕获组 *)([0-9]{2})
-匹配2位数字(* 第3个捕获组 *)(-{0,1}[0-9]{4})
-匹配可选的-
+ 4位数字(* 第4个捕获组 *)XXX\2XX\4
-用XXX
替换第1个捕获组,按原样打印第2个捕获组,用XX
替换第3个捕获组,按原样打印第4个捕获组g
-应用于一行中的所有匹配项这会产生:
h5qlskok5#
Grep反转匹配正则表达式(已修复):
Grep选项:
-v
:反转匹配(打印不匹配的所有内容)。-E
:使用模式的扩展正则表达式语法。正则表达式详细信息:
([^0-9]|^)
:匹配非数字或行首。[0-9]{3}-?
:匹配3个数字,后面可以跟一个短划线。[0-9]{2}-?
:匹配2个数字,后面可以跟一个短划线。[0-9]{4}
:匹配4位数字。([^0-9]|$)
:比对非数字或行尾。测试
测试输出: