如何仅从文本文件的第一行和最后一行提取数据

时间:2010-11-12 00:21:58

标签: linux bash awk

我有一个运行时间很长的程序,my_prog有一些我要解析的输出,以获得两个变量,$ start和$ end。这是输出的样子:

Important data between the first set of pipes|3|a|
This line is not interesting to me|5|c|
...
Another line with data (at the end this time)|4|b|

在上面的示例中,我只需要:

start=3
end=b

我在bash脚本中使用它。我有一种感觉awk可以完全解决这个问题,但做一个start=$(my_prog|awk ...)只会给出一个变量。我想我可以做my_array=($(my_prog|awk ...)),但这看起来很混乱。另外,我不想将my_prog的(可能很长的)输出放入变量中。获取数据的好方法是什么?可以用某种方式直接写入bash变量吗?

4 个答案:

答案 0 :(得分:2)

当@Zack写入awk脚本时,唯一的改进可能是:

read start end < <(my_prog | 
  awk -F\| 'NR==1 { start=$2 } END { print start " " $3 }')

答案 1 :(得分:1)

我就是这样做的(完全未经测试):

startend=$(my_prog | 
    awk -F\| 'NR==1 { start=$2 } { end=$3 } END { print start "|" end }')
start=${startend%|*}
end=${startend#*|}

答案 2 :(得分:1)

无需在文件的每一行上进行分配。最后一条记录在END子句中可用,因此您甚至不需要在那里进行分配。

此外,AWK保留一个单独的OFS(输出字段分隔符),因此您可以在打印时使用输出变量之间的逗号。

delim=" "   # or choose one that suits you
read -r -d "$delim" start end < <(my_prog | 
  awk -F\| -v OFS="$delim" 'NR==1 { start=$2 } END { print start, $3 }')

或者,您可以使用here字符串或此处doc来代替进程替换< <()

read ... <<< $(my_prog ...)

read ... <<EOF
$(my_prog ...)
EOF

要完成读取任务,可以将my_prog / awk管道放在函数中:

foo () { my_prog | awk ... ; }

read ... < <(foo)    # or one of the other redirection methods

答案 3 :(得分:0)

还可以评估: eval `myprog | awk -F\| 'NR==1 { start=$2 } { end=$3 } END { print "start="start " end="end }'`