使用sed将两个数字模式之间的数据复制到一个新文件

时间:2014-01-29 00:13:11

标签: sed tcsh

我正在运行一堆(~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,因为我的服务器正在运行。

3 个答案:

答案 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