我有一个具有这种一般结构的输入文件。我只想从山块中提取值步长和权重,并使用 awk/sed/grep 将它们放入输出文件中。山块在输入文件中以类似的方式排列。
编辑:我正在使用 MAC OSX。
configuration {
step 5000
dt 2.000000e+00
}
colvar {
name d1
x 1.70882305580118e+01
v 0.00000000000000e+00
}
1.85104129628346e-02 9.71380137561312e-02 4.00538287370335e-02
1.25662994200839e-02 9.88655406140091e-02 1.41657757894898e-01
hill {
step 0
weight 1.00000000000000e-01
centers 1.23563844380284e+02
widths 1.25331413731550e+00
}
hill {
step 100
weight 1.00000000000000e-01
centers 1.19065310650377e+02
widths 1.25331413731550e+00
}
通过其他一些答案,我设法找到了一些帮助:-
sed 's/^.*weight//' diol_colvar.colvars.state > hill.txt
sed 's/^.*step//' diol_colvar.colvars.state > hill.txt
遗憾的是这并没有按照我想要的方式工作。
我希望我的输出是这样的:-
0 1.00000000000000e-01
100 1.00000000000000e-01
请帮我解决这个问题。
谢谢,
答案1
1) 与sed
假设step
和weight
出现在连续行中,
$ sed -nE '/step/{N;s/.*step\s+(\S+).*\n.*weight\s+(\S+).*/\1\t\2/p}' ip.txt
0 1.00000000000000e-01
100 1.00000000000000e-01
-nE
默认情况下不打印行并使用扩展正则表达式/step/
匹配如果行包含step
N
得到下一行
笔记:
以上是在 上测试过的GNU sed 4.2.2
。以下内容可能对 OS X 和其他版本有所帮助。看关于 SO 的问答详细信息,要点是\s
可能与 GNU sed 工作方式不同
sed -nE '/step/{N;s/.*step[[:space:]]+([^[:space:]]+).*\n.*weight[[:space:]]+([^[:space:]]+).*/\1\t\2/p}' ip.txt
2) 与awk
$ awk 'a ~ /step/ && /weight/{print v"\t"$2} {a=$0; v=$2}' ip.txt
0 1.00000000000000e-01
100 1.00000000000000e-01
{a=$0; v=$2}
保存该行和第二个字段a ~ /step/ && /weight/
step
如果上一行包含并且当前行包含则匹配weight
假设hill
块都与给定的输入相似,我们可以匹配三个连续行以将匹配限制为仅hill
块
awk 'b ~ /hill/ && a ~ /step/ && /weight/{print v"\t"$2} {b=a; a=$0; v=$2}' ip.txt
要保存结果,请添加> output_filename
到命令末尾
参考:
答案2
使用 awk 两次更容易:第一次提取hill { }
块,第二次提取步长/权重值。
awk '/hill *{/,/}/ {print}' \
| awk '$1 == "step" { st = $2 }; $1 == "weight" { print st "\t" $2}'
weight
该命令仅在后面出现step
但不需要连续行时才有效。