file1, file2, file3
名前が...次の形式のファイルがあるとしましょう。
ファイル1
blah blah blah
[PATTERN0]
a10
a20
a30
[PATTERN1]
a11
a21
a31
[PATTERN3]
a13
a13
a33
ファイル2
blah blah blah
[PATTERN0]
b10
b20
b30
[PATTERN1]
b11
b21
b31
[PATTERN3]
b13
b13
b33
私が望むのは、特定のパターン(PATTERN0など)に従うすべてのファイルの各個々のエントリの合計を含むファイルで終わることです。たとえば、ファイルには次のものが必要です。
a10+b10
a20+b20
a30+b30
これまでは、rradを使用して値のみを印刷できます。
awk '/PATTERN0/ {for(i=1; i<=3; i++) {getline;print $1}}' file*
どうすればいいのかご存知ですか?
答え1
のawk
場合、常に2つ以上のファイルがあると仮定すると、すべてのファイルはとの間[PATTERN0]
に同じ数の行があり、[PATTERN1]
その行は実際には数字です。
awk '
BEGIN {
# discard the garbage before [PATTERN0]
for (i = 1; i < ARGC; i++) {
do
getline str <ARGV[i]
while (str !~ /\[PATTERN0\]/)
}
# read sum from first file, then add numbers in turn from the other files
while ((getline sum <ARGV[1]) && sum !~ /\[PATTERN1\]/) {
for (i = 2; i < ARGC; i++) {
getline nr <ARGV[i]
sum += nr
}
print sum
}
}' file1 file2 file3 ...
答え2
Paste + awkを組み合わせると良い結果が得られます。
$ paste -d"+" file1 file2 |awk -F"[+]" '/PATTERN/{print $1;next}1'
私はそれを避けるためにawkを呼び出します[PATTERN0]+[PATTERN0]
- あなたはそれを削除することができます。または、まったく印刷したくない場合は、[PATTERN]
最後のawkを次に変更します。
...|awk -F"[+]" '/PATTERN/{next}1
テスト:
$ paste -d"+" <(echo "$a") <(echo "$b") |awk -F"[+]" '/PATTERN/{next}1'
a10+b10
a20+b20
a30+b30
a11+b11
a21+b21
a31+b31
a13+b13
a13+b13
a33+b33
単純なawkソリューションもあります。
$ awk -v RS="[PATTERN[0-9]+]" '{for (i=1;i<=NF;i++) (NR==FNR)?a[RT][i]=$i:a[RT][i]=a[RT][i] "+" $i} \
END{for (k in a) for (l in a[k]) print a[k][l]}' <(echo "$a") <(echo "$b")
PS:上記のawkは.awkを削除すると1行になります\
。読みやすくするために2行に分けました。
このawkのトラップはENDセクションでの印刷は正確ですが、awkがこのforメソッドを使用して配列を印刷する方法により、印刷はランダムなPATTERN順序で行われます(つまり、[PATTERN3]
データは代わりに最初に印刷されます)。[PATTERN0]