Sed - 如果模式不匹配,则停止多部分命令? [英] Sed - stop multi-part command if pattern doesn't match?

查看:74
本文介绍了Sed - 如果模式不匹配,则停止多部分命令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

全部,我正在尝试运行 sed 命令以从某些文件中去除卡号.我试图在单行中做到这一点,我认为一切都很顺利 - 但我意识到如果我的第一个替代品与模式不匹配,它会继续执行下一个命令.如果没有匹配,有没有办法让它退出?

All, I'm trying to run a sed command to strip out card numbers from certain files. I was trying to do this in a one-liner and I thought all was going well - but I realized that if my first substitute didn't match the pattern it continued into the next commands. Is there a way to get it to exit if there is no match?

我们的系统上有 16-22 个长度的卡号,所以我写这个时考虑了可变长度.我的规范是保留任何 16 位以上数字的前 6 位和后 4 位,并使用 ax(星号)去掉中间的任何内容.

We have 16-22 length card numbers on our system, so I wrote this with a variable length in mind. My specifications were to preserve the first 6 and last 4 of any 16+ digit number, and axe (asterisk) out anything in the middle.

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/'

问题在于如果这部分命令:

The problem lies in the fact that if this part of the command:

s/[0-9]\{6\}\([0-9]\{5\}\)\([0-9]*\)[0-9]\{4\}/\1\2/

什么也没找到,模式空间仍然是输入.它继续到下一个命令,然后用星号替换所有内容.我最终得到的是输入后跟相同数量的星号(如果它与我的第一个替代品中的卡号资格"不匹配).如果被认为是可能的卡号,它就可以完美运行.

Finds nothing, the pattern space remains the input. It continues into the next command which then replaces everything with asterisks. What I end up with is the input followed by an equal number of asterisks (if it does not match the "card number qualifications" in my first substitute). It works perfectly if it is what is deemed a possible card number.

有什么想法吗?

推荐答案

但我意识到如果我的第一个替代品与模式不匹配继续下一个命令.有没有办法让它退出,如果没有匹配项?

but I realized that if my first substitute didn't match the pattern it continued into the next commands. Is there a way to get it to exit if there is no match?

您可以使用分支命令.我添加并评论了它们:

You can use branch commands. I added and commented them in place:

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

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

这篇关于Sed - 如果模式不匹配,则停止多部分命令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆