我正在运行一堆(~320)计算化学实验,我需要从每个文件中提取少量数据,以便我可以在MatLab中对它进行一些工作。
我很确定我可以使用sed来完成这项工作,但请尝试我似乎无法做到这一点。
我需要从以“1 1”开头并以“33 33”开头的行开头的所有数据。
I J FI(I,J) k(I,J) K(I,J)
1 1 -337.13279 -0.06697 -0.00430
2 2 3804.89120 8.52972 0.54787
3 3 3195.69653 6.01702 0.38648
4 4 3189.18684 5.99253 0.38490
5 5 3183.73262 5.97205 0.38359
6 6 3174.47525 5.93737 0.38136
7 7 3167.88746 5.91275 0.37978
8 8 1628.80868 1.56311 0.10040
9 9 1623.56055 1.55306 0.09975
10 10 1518.21620 1.35806 0.08723
11 11 1476.93012 1.28520 0.08255
12 12 1341.24087 1.05990 0.06808
13 13 1312.30373 1.01466 0.06517
14 14 1264.73004 0.94242 0.06053
15 15 1185.62592 0.82822 0.05320
16 16 1175.54013 0.81419 0.05230
17 17 1170.41211 0.80710 0.05184
18 18 1090.20196 0.70027 0.04498
19 19 1039.29190 0.63639 0.04088
20 20 1015.00116 0.60699 0.03899
21 21 1005.05773 0.59516 0.03823
22 22 986.55965 0.57345 0.03683
23 23 917.65537 0.49615 0.03187
24 24 842.93089 0.41863 0.02689
25 25 819.00146 0.39520 0.02538
26 26 758.39720 0.33888 0.02177
27 27 697.11173 0.28632 0.01839
28 28 628.75684 0.23292 0.01496
29 29 534.75856 0.16849 0.01082
30 30 499.35579 0.14692 0.00944
31 31 422.01320 0.10493 0.00674
32 32 409.30255 0.09870 0.00634
33 33 227.12411 0.03039 0.00195
33 2nd derivatives larger than 0.371D-04 over 561
MatLab不是文本的粉丝,所以我不想使用文本分隔符(虽然这个数据部分的标题中有一些)并且只将数据包含在数字行中。
数据文件也包含很多其他数字,所以我需要匹配行开头的“1 1”和复制结尾的“33 33”。这些“指数”仅存在于此信息块中。
我试图使用
% sed -n /"1 1"/,/"33 33"/p input.file > output.file
但是我在输出文件中得到了一个完整的数据,因为它复制了在“1”和“33”之间显示的所有内容
有什么方法可以做我正在寻找的东西吗?
另外,我正在使用tcsh,因为我的服务器正在运行。
答案 0 :(得分:1)
你的问题是双重的。首先,它们之间有两个空白,但你的正则表达式只允许一个(从现在缩进的代码判断)。其次,你可能不够精确;例如,/1 1/
模式与11 11
匹配,111 111
等等。
所以,你应该考虑:
sed -n -e '/^ *1 *1 /,/^33 *33 /p' -e '/^33 33 /q' input.file > output.file
模式由^
(插入符号)锚定到行首。这些数字由一个或多个空格分隔(在标准sed
中还有其他较长的写作方式; +
选项不是标准sed
,但广泛可用)。数字以空白终止。很可能只有第一个表达式会给你你想要的东西。第二个表达式在识别33 33
输入行时会提前终止搜索,如果输入文件足够大,可以节省大量文件I / O,从而节省处理时间。
如果具有数百个ID号的行具有不同的格式,那么调整正则表达式以匹配使用的内容应该相当简单。如果数据包含选项卡而不是(或者)空白,则可以调整正则表达式来管理它。
答案 1 :(得分:1)
如何使用awk
awk '$1=="1"&&$2=="1"{t=1};t;$1=="33"&&$2=="33"{t=0}' file
@ mklement0推荐,如果只有一个块,为避免处理文件的其余部分,您可以将命令更新为:
awk '$1=="1"&&$2=="1"{t=1};t;$1=="33"&&$2=="33"{exit}' file
答案 2 :(得分:0)
如果数据的格式与此文件完全相同,则可以使用sed只读取第3行到第35行(行1 1 - 33 33)。这比解析值要容易得多,但确实要求文件具有标准格式:
sed -n 3,35p data.txt
另一种便宜的方法是只使用数字线grep,只采用前33:
grep "^[0-9 ][0-9 .-]*$" data.txt | head -n 33