全部,我正在尝试运行sed
命令从某些文件中删除卡号。我试图在一个单行中做这个,我认为一切进展顺利 - 但我意识到如果我的第一个替代品与模式不匹配,它会继续进入下一个命令。如果没有匹配,有没有办法让它退出?
我们的系统上有16-22个长度卡号,所以我写了一个可变长度。我的规格是保留任何16位数字的前6位和后4位,以及中间任何位置的斧头(星号)。
sed 'h;s/[0-9]\{6\}\([0-9]\{5\}\)\([0-9]*\)[0-9]\{4\}/\1\2/;s/./*/g;x;s/\([0-9]\{6\}\)[0-9]*\([0-9]\{4\}\)/\1\2/;G;s/\n//;s/\([0-9]\{6\}\)\([0-9]\{4\}\)\(.*\)/\1\3\2/'
问题在于如果命令的这一部分:
s/[0-9]\{6\}\([0-9]\{5\}\)\([0-9]*\)[0-9]\{4\}/\1\2/
什么都没找到,模式空间仍然是输入。它继续进入下一个命令,然后用星号替换所有内容。我最终得到的是输入后跟相同数量的星号(如果它与我的第一个替换中的“卡号资格”不匹配)。如果 被认为是可能的卡号,它就能完美运行。
有什么想法吗?
答案 0 :(得分:2)
但我意识到,如果我的第一个替代品与它的模式不符 继续进入下一个命令。有没有办法让它退出if 没有比赛?
您可以使用分支命令。我添加并评论了它们:
sed '
h;
s/[0-9]\{6\}\([0-9]\{5\}\)\([0-9]*\)[0-9]\{4\}/\1\2/;
## If last substitution command succeeds, go to label "a".
t a
## Begin next cycle (previous substitution command didn't succeed).
b
## Label "a".
:a
s/./*/g;
x;
s/\([0-9]\{6\}\)[0-9]*\([0-9]\{4\}\)/\1\2/;
G;
s/\n//;
s/\([0-9]\{6\}\)\([0-9]\{4\}\)\(.*\)/\1\3\2/
'
更新。
所以你要转型
texttexttext111111222223333texttexttext
in
texttexttext111111*****3333texttexttext
尝试:
echo "texttexttext111111222223333texttexttext" |
sed -e '
## Add newlines characters between the characters to substitute with "*".
s/\([0-9]\{6\}\)\([0-9]\{5\}\)\([0-9]*\)\([0-9]\{4\}\)/\1\n\2\3\n\4/;
## Label "a".
:a;
## Substitute first not-asterisk character between newlines with "*".
s/\(\n\**\)[^\n]\(.*\n\)/\1*\2/;
## If character before second newline is not an asterisk, repeat
## the substitution from label "a".
/^.*\*\n/! ta;
## Remove artificial newlines.
s/\n//g
## Implicit print.
'
输出:
texttexttext111111*****3333texttexttext
答案 1 :(得分:1)
来自man sed
:
t label
If a s/// has done a successful substitution since the last
input line was read and since the last t or T command, then
branch to label; if label is omitted, branch to end of script.
T label
If no s/// has done a successful substitution since the last
input line was read and since the last t or T command, then
branch to label; if label is omitted, branch to end of script.
This is a GNU extension.
所以我认为您可以在第一个T;
命令之后添加s
。