ここで利用可能な以前の質問をいくつか見つけようとしましたが、残念ながら正確なケースが見つかりませんでした。
他のコマンドの出力から次のような結果を得たいと思います。
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
一致する行に設定しpattern
、c=0
残りの行に設定し、数字で始まらないすべての行に設定し(ブロック内END
)c
、すでに設定されていること(または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つ以上なく、pattern
GNU 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
仕組み:
- 現在の行が
pattern
thenで始まる場合- 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