【发布时间】:2018-02-15 18:50:54
【问题描述】:
我想从一个 ASCII 文件中提取数据,该文件看起来像此处提供的以 1NAME 开头的块。以 1NAME 开头的块可以重复任意次数 - 我的文件只有一个块,有些文件多达 744 个:
AVERAGE MODELNAME -- RUNNAME
0 1 11121 0. 11122 24.
-9700000 4000000 0 -241200000000 -1620000
1.00000 1000.00000 10 10 1 2 0 15. 11. 0.
1 1 500 400
NAME
11121 0.00 11121 1.00
1NAME
0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00
0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00
0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00
NAME
11121 1.00 11121 2.00
1NAME
1.0000000E+00 45.0000000E+00 01.0000000E+00 115.0000000E+00 5.0000000E+00
2.0000000E+00 66.0000000E+00 09.0000000E+00 180.0000000E+00 4.0000000E+00
3.0000000E+00 80.0000000E+00 70.0000000E+00 130.0000000E+00 5.0000000E+00
我想从 (1) 文件中给定的重复位置中提取值,从“1NAME”之后开始,(2) 通过管道输出到文本文件并创建标头来标识它是从哪个位置提取的,以及 (3)创建一个自定义代码,该代码可以在 1NAME 之后接收多个位置(例如记录 1、5、8)的输入,并将它们输出到单独的输出中(例如:位置 1 的所有记录的一个输出,位置 5 的一个输出文件,.. .)。
例如,我想在给定的输入文件中获取 1NAME 之后的记录 1、5 和 8。每条记录的输出应在标记为 GRID#.txt 的单独记录特定文本文件中按如下方式输出:
GRID 1
0.0000000E+00
00.0000000E+00
GRID 5
0.0000000E+00
5.0000000E+00
GRID 8
0.0000000E+00
09.0000000E+00
我能够使用 sed 一次提取数据。但是我需要从输入文件的多个位置提取数据。所以我试图把所有的信息放在一个脚本中。以下是我采取的步骤。
-
输入文件有多个空格和不一致的空行。所以我用 sed 去掉了多个空格,换成了一个空格。然后使用此步骤的管道输出,删除所有空行。这导致文件中的所有数据按每行一个值排列。
sed 's/\s\+/\n/g' <input.txt>| sed '/^$/d -
为了提取数据,然后我从步骤 1 的管道输出中使用了 sed 命令(格式如下)。
sed -n -e 11p -e 50p -
我尝试将所有这些命令作为带有自定义行号的 bash(或 csh,任一选项)脚本。我尝试(天真地)使用 foreach,然后了解到它不能在 bash 中使用。我将改用其他用户推荐的脚本。
#!/bin/bash set FILE=$cwd/sample_or_2day foreach GRID (23729) foreach GRIDTIME(28 41) sed 's/\s\+/\n/g' $FILE | sed '/^$/d' | sed '1,36d' > temp_out sed -n -e "$GRIDTIME" temp_out | tee $cwd/out_$GRID
感谢您的耐心等待。我是一个紧张的程序员,正在努力掌握基础知识。我花时间查看 sed 指令页面和用户支持论坛。欢迎任何建议 - 特别是有明确的说明。谢谢!
【问题讨论】:
-
给定上面的输入,你想要哪个输出?
-
我已经更新了#3下的输入输出文件格式和格式化代码
-
foreach在bash中不存在。它是for,而不是foreach,它支持两种不同的语法,这两种语法都与您使用的完全不同。help for将向您展示两者。 -
注意,foreach 可以与 csh 一起使用吗?我无法很好地解释帮助页面。
-
如果您询问的是
csh而不是bash(一种完全不同的语言),请相应地标记您的问题。您使用的 for 循环语法确实来自csh,但它缺少end语句来关闭重复块。在 21 世纪没有充分的理由使用csh