0

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/

何も見つかりません。パターンスペースは入力のままです。次のコマンドに進み、すべてがアスタリスクに置き換えられます。最終的には、入力の後に同数のアスタリスクが続きます(最初の代用の「カード番号の資格」と一致しない場合)。それが可能なカード番号と見なされるものである場合、それは完全に機能します。

何か案は?

4

2 に答える 2

2

しかし、私の最初の代用者がパターンと一致しなかった場合、それは次のコマンドに続くことに気づきました。一致するものがない場合に終了させる方法はありますか?

ブランチコマンドを使用できます。私はそれらをその場で追加してコメントしました:

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
于 2012-09-24T20:03:01.743 に答える
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コマンドの後に追加するだけでよいと思います。

于 2012-09-24T20:00:13.047 に答える