値がまったく見つからない場合は、値を含む新しい行を挿入します。

値がまったく見つからない場合は、値を含む新しい行を挿入します。

ここで利用可能な以前の質問をいくつか見つけようとしましたが、残念ながら正確なケースが見つかりませんでした。

他のコマンドの出力から次のような結果を得たいと思います。

pattern.d
17.91
17.55
pattern.b
pattern.a
7.21
9.34
pattern.c

これに関して:

pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000

もう少し説明しようとしています。 "pattern"という文字列を含む各行の後には常に数字が必要です。そうでない場合は、値が1000の新しい行を挿入したいと思います。

パターンには、後で内容をアルファベット順に並べ替えるのに役立つ変更される「拡張子」(.a .b .c .dですが、「拡張子」の数字はありません)があります。

編集:答えを受け入れましたが、まだ別のバリエーションを探している人がいる場合は、「パターン」が異なるように指定する必要があります。

pattern.a
pattern.d
pattern.c
pattern.d
pattern.b
17.91

答え1

以下は、sedすべての入力(たとえば、複数の連続した一致pattern)に対して機能するソリューションです。

sed '1{                   # when on first line
x                         # exchange
s/^/1000/                 # replace the empty hold buffer with "1000"
x                         # exchange back
}
: do                      # label "do"
/pattern/{                # if the current line matches "pattern"
${                        # if we're on the last line
G                         # append hold buffer content to pattern space
b                         # go to end of script
}
n                         # otherwise print and pull in the next line
/^[[:digit:]]/!{          # if this one doesn't start with a digit
x                         # exchange
p                         # print (the pattern space is now "1000")
x                         # exchange back
b do                      # go to label "do"
}
}' infile

それでgnu sed私達は書くことができます

sed '1{x;s/^/1000/;x};:b;/pattern/{${G;b};n;/^[[:digit:]]/!{x;p;x;bb}}' infile

次のようにすることができますawk

awk -vc=0 '!/^[[:digit:]]/{
if (c) {print "1000"}
}
{ if (/pattern/){c=1} else{c=0}
}
END{if (c){print "1000"}
};1' infile

つまり、c=1一致する行に設定しpatternc=0残りの行に設定し、数字で始まらないすべての行に設定し(ブロック内ENDc、すでに設定されていること(または1前の行が一致することを意味pattern)を確認します。 printなら1000

答え2

sed -e '
   $!{
      /pattern\.[a-z]/N
      /\n/!b
      /\n[+-]\{0,1\}[.][0-9]\{1,\}$/b
      /\n[+-]\{0,1\}[0-9]\{1,\}\([.][0-9]*\)\{0,1\}$/b
      h;s/\(.*\n\).*/\11000/p
      g;D
   }
   /pattern\.[a-z]/a\
1000
' yourfile

結果

pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000

布材

  • eof時点ではありませんが、$!{...}現在の行が関心のある行である場合は、パターンスペースに次の行を追加します。
  • その後、次の場合は追加の処理をスキップします。 a) 改行が見つかりません => 現在行にパターンがありません。 b) 2行目は.nnn形式の浮動小数点数です。 c)mmm、mmm、またはmmm.nnnの形式の浮動小数点数は、2行目にのみ表示されます。 d) 可能性を排除する => 改行文字 次の行の最後にマジック番号 1000 を追加する必要があります。

答え3

ifの連続したインスタンスは2つ以上なく、patternGNU sedがある場合:

sed '/^pattern/ {$!N; /\n[0-9]/b; s/$/\n1000/M}' file
pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000

仕組み:

  • 現在の行がpatternthenで始まる場合
    • EOF でない場合は、次の行を追加します。
    • 改行の後に数字がある場合(より具体的になる可能性がある)、b終了します(つまり、次の行に進みます)。
    • 終了する最初の行を改行文字に置き換えます。1000

GNU固有のM修飾子は、$一致または「一般」ケースとEOFケースを処理\nできます$(次の行は追加されません)。

答え4

アッ解決策:

awk '{ if ($0 ~ /pattern/) {      # if it's a `pattern` line
         if ((getline nl) > 0) {  # check if next record exists
             # if next record hasn't number - insert `1000`, otherwise - print current and next records as they are
             print ((nl !~ /^[0-9]/)? $0 ORS 1000 ORS nl: $0 ORS nl)
         } else {
             print $0 ORS 1000   # if the file ends up with pattern - insert `1000`
         } 
       } else {
          print $0  # print other record
       }
    }' file

出力:

pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000

関連情報