将行连接到文本文件中的列表

时间:2017-08-13 21:28:41

标签: bash text awk

我有这个txt文件,其中包含音频文件某些部分的概率。

示例:

K-0_0_1_0_1_0_1_1_8547  [
  0 0 1 ]
K-0_0_1_0_1_0_1_1_23086  [
  1 1.191074e-27 1.574905e-26 ]
K-0_0_1_0_1_0_1_1_23781  [
  0 0 1 ]
K-0_0_1_0_1_0_1_1_3732  [
  0 0 1 ]
K-0_0_1_0_1_0_1_1_13964  [
  0 0 1 ]
K-0_0_1_0_1_0_1_1_3098  [
  1 0 0 ]
K-0_0_1_0_1_0_1_1_8296  [
  0 0 1 ]
K-0_0_1_0_1_0_1_1_1780  [
  0 0 1 ]
K-0_0_1_0_1_0_1_1_21968  [
  1 1.377321e-38 0 ]

其中所需的输出应为

K-0_0_1_0_1_0_1_1 [
0 0 1 
1 0 0
0 0 1
0 0 1
0 0 1
0 0 1
1 1.377321e-38 0
1 1.191074e-27 1.574905e-26
0 0 1 ]

输入文件的结构如下

filename_pieces [ probability_1 probability_2 probability_3 ]

我想将文件名的所有部分收集到一个 概率的组合列表,其中位置按升序排列。

所以在这种情况下,组合列表应该像这样构建

_1780
_3098
_3732
and so on.. 

我目前正在使用此脚本的方式..

awk 'NF == 2{ match($1,/^[0-9]+(_[0-9]+){7}/); k = substr($1,RSTART,RLENGTH); next }
     { $NF=""; a[k]=a[k]"\n "$0 }
     END { for(i in a) printf "%s [%s ]\n\n",i,a[i] }' 

但是这似乎并不喜欢文件名前面的K-,这是至关重要的。不过我可以改变脚本来处理这个问题。之前的有效文件名仅为0_0_1_0_1_0_1_1,因此没有K-前面的数字。

1 个答案:

答案 0 :(得分:1)

根据您的脚本,但按文件部分添加排序(最后一个数字用下划线分隔)并按文件名组合,脚本看起来像这样(为了便于阅读,扩展到多行):

#!/usr/bin/awk -f

NF == 2 {
    match($1, /_[0-9]+$/)
    filename = substr($1, 0, RSTART-1)
    part = substr($1, RSTART+1, RLENGTH)
    next
}

{ 
    $NF = ""
    all[filename][part] = $0
}

END {
    for (filename in all) {
        n = asorti(all[filename], sorted, "@ind_num_asc")
        printf "%s [", filename
        for (i=1; i<=n; i++) {
            printf "\n%s", all[filename][sorted[i]]
        }
        print "]"
    }
}

首先,我们将所有部件存储在二维数组中,按文件名和部件号​​进行组织。最后,对于遇到的每个文件,我们按索引升序排序(这是部件号),然后按顺序打印文件的所有部分。

在您的示例输入上运行它,我们得到:

$ awk -f join.awk audio
K-0_0_1_0_1_0_1_1 [
0 0 1 
1 0 0 
0 0 1 
0 0 1 
0 0 1 
0 0 1 
1 1.377321e-38 0 
1 1.191074e-27 1.574905e-26 
0 0 1 ]