从文件中提取信息并将其作为列添加到另一个文件

时间:2015-07-11 16:58:19

标签: bash awk sed paste

我有这个文件(test.txt):

###########
###########
1x1 1y1
1x2 1y2
###########
###########
2x1 2y1
2x2 2y2
###########
###########
3x1 3y1
3x2 3y2
  

1x1,1x2,1Y1,1Y2等。表示十进制,正数和负数   数量

     #      #对应于文本和数字标题是不想处理的值。每个包含9行以数字开头      

或信件。

我想用管道生成这个输出文件(output.txt):

 1x1 1y1 2x1 2y1 3x1 3y1
 1x2 1y2 2x2 2y2 3x2 3y2

尝试:(test.sh)

touch output.txt

paste -d' ' output.txt <(sed '5,12d' test.txt | sed '1,2d' | awk '{print $1" "$2}') > output.txt
paste -d' ' output.txt <(sed '9,12d' test.txt | sed '1,6d' | awk '{print $1" "$2}') > output.txt
paste -d' ' output.txt <(sed '1,10d' test.txt | awk '{print $1" "$2}') > output.txt

结果: cat output.txt

3x1 3y1
3x2 3y2

我的脚本出错了?

我忘了提到test.txt文件实际上有1,000,000行。因此,我想有效地做到这一点。我通过使用辅助文件解决了这个问题,但性能非常慢。这就是我不想使用辅助文件的原因。

此致

3 个答案:

答案 0 :(得分:1)

paste <(grep "^1x" test.txt)  <(grep "^2x" test.txt) <(grep "^3x" test.txt)
1x1 1y1 2x1 2y1 3x1 3y1
1x2 1y2 2x2 2y2 3x2 3y2

编辑:将此作为骨架使用(无需拨打paste 3次):

paste <(grep <your_regex_1> test.txt) \
      <(grep <your_regex_2> test.txt) \
      <(grep <your_regex_3> test.txt)

答案 1 :(得分:1)

如果输入中总是有两列数字,那么您总是有两行输出:

awk 'NF==2 {row1=row1 $0 " "; getline; row2=row2 $0 " "} END {print row1; print row2}' test.txt

输出:

1x1 1y1 2x1 2y1 3x1 3y1 
1x2 1y2 2x2 2y2 3x2 3y2   

如果####行可能包含两个字段,则必须将目标NF==2调整为更具体的字段。

答案 2 :(得分:0)

这可能适合你(GNU sed):

sed -r '/^\S+ \S+/N;//H;$!d;x;s/.//;:a;s/^([^\n]*)\n([^\n]*)\n([^\n]*)\n([^\n]*)/\1 \3\n\2 \4/;ta' file

这会将所需数据保存在保留空间中,然后使用模式匹配来构建所需的输出。