次のファイルがあります。
# Time-averaged data for fix avetimeall
# TimeStep Number-of-rows
# Row c_gyrationchunkall
1000 3
1 2.09024e-14
2 4.88628
3 5.69321
2000 3
1 2.10518e-14
2 8.33702
3 8.83162
3000 3
1 1.96656e-14
2 12.1396
3 11.5835
...
私のファイルでは、最初の3行は常にヘッダです。ヘッダーの後には、私のファイルに同じサイズのチャンクがリストされており、それぞれはタグサブヘッダーで始まります。各チャンクのデータがそのチャンクラベルの関連部分で始まる行に転送されるようにファイル内のデータを再構成し、そのチャンクの関連データ値をすべてスペースで区切ってリストしたいと思います。たとえば、上記の例を次のように変換したいとします。
# Time-averaged data for fix avetimeall
# TimeStep c_gyrationchunkall
1000 2.09024e-14 4.88628 5.69321
2000 2.10518e-14 8.33702 8.83162
3000 1.96656e-14 12.1396 11.5835
...
Bashでこれを行うにはどうすればよいですか? Bashの経験は少しありますが、この問題をすばやく処理するのに十分ではありません。
ベストアンサー1
3
ブロックの行数が異なる可能性があるかどうかに関係なく、awkを使用してください。
$ awk '
NR == 2 { $3=""; saved=$0; next }
NR == 3 { $0=saved $3 }
NR < 4 { print; next }
!numLines {
numLines = $2
printf "%s%s", $1, OFS
next
}
{ printf "%s%s", $2, (--numLines ? OFS : ORS) }
' file
# Time-averaged data for fix avetimeall
# TimeStep c_gyrationchunkall
1000 2.09024e-14 4.88628 5.69321
2000 2.10518e-14 8.33702 8.83162
3000 1.96656e-14 12.1396 11.5835
以下の議論を続けてください。ザビエルGの答え読みやすさスタイルのデフォルト設定に関して、以下はシェルスクリプトと同じスタイルで書かれたawkスクリプトです(シェルスクリプトに含まれているため、外部でも同じように機能します)。しかし、はるかに速く実行されます*シェルスクリプトよりも強力で移植可能です。 :
$ cat ./script_filename
#!/usr/bin/env bash
awk '
BEGIN {
# Reformat comments:
getline first_line
print first_line
getline; split($0,line2)
getline; split($0,line3)
printf "# %s %s\n", line2[2], line3[3]
# Reformat data:
while ( getline > 0 ) {
timestep=$1; number_of_rows=$2
printf "%s", timestep
for ( i=1; i<=number_of_rows; i++ ) {
getline; row_value=$NF
printf " %s", row_value
}
print ""
}
}
'
$ ./script_filename < input
# Time-averaged data for fix avetimeall
# TimeStep c_gyrationchunkall
1000 2.09024e-14 4.88628 5.69321
2000 2.10518e-14 8.33702 8.83162
3000 1.96656e-14 12.1396 11.5835
*以下は、90,000個のOPレコードを含むファイルでbashスクリプトと上記のawkスクリプトを3回目に実行したタイミングの結果です。
$ time ./script_bash < file > /dev/null
real 0m9.425s
user 0m5.062s
sys 0m4.139s
$ time ./script_awk < file > /dev/null
real 0m0.265s
user 0m0.171s
sys 0m0.000s