开发者

How to pull data from only the first and last lines of a text file

I have a long running program, my_prog that has some output that I want to parse to get two variables, $start and $end. Here's what the output might look like:

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|

In the example above, I just need:

start=3
end=b

I'm using this in a bash script. I have a feeling awk can totally solve this issue, but doing a start=$(my_prog|awk ...) will g开发者_运维问答ive only one variable. I guess I could do a my_array=($(my_prog|awk ...)), but that just seems messy. Also, I don't want to put the (possibly long) output of my_prog into a variable. What's a good, simple way to get that data? Can awk somehow write directly to the bash variables?


as @Zack wrote awk script is ok, the only improvement could be:

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


This is how I would do it (totally untested):

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


There's no need to do an assignment on each line of the file. The last record is available in the END clause so you won't even need to do an assignment there.

Also, AWK keeps a separate OFS (output field separator) so you can use a comma between your output variables when you print them.

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 }')

Alternatively, instead of process substitution < <(), you can use a here string or a here doc:

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

or

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

To neaten up the read assignment, you can put your my_prog/awk pipe in a function:

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

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


One could also eval: eval `myprog | awk -F\| 'NR==1 { start=$2 } { end=$3 } END { print "start="start " end="end }'`

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜