генерировать новые файлы итеративно в соответствии со строками из другого - PullRequest
0 голосов
/ 03 июня 2019

У меня есть два разных файла, из которых я хочу извлечь несколько строк и сгенерировать новые файлы. Мой первый файл выглядит так: file1.tsv:

A       B       C       D       E       Example  Set     Group
0       0       27      0       0       exA sub9    1
0       0       45      12      12      exA sub14   0
1       1       45      14      6       exA sub6    0
2       2       65      7       8       exA sub2    1
3       3       68      9       14      exA sub13   0
4       4       70      8       13      exA sub5    0
5       5       75      3       11      exA sub8    1
6       6       79      10      7       exA sub7    1
7       7       85      13      5       exA sub12   1
8       8       88      5       4       exA sub1    0
9       9       90      1       1       exA sub10   1
10      10      92      2       2       exA sub3    0
11      11      98      4       3       exA sub4    1
12      12      108     12      10      exA sub11   1

Мой второй файл - векторный файл2.vec:

1 1:3.000 2:0.000 3:0.000 4:4.000 5:0.000 #(Aid=sub1, Bid=exA, group=1)
2 1:0.000 2:1.000 3:2.000 4:5.000 5:0.000 #(Aid=sub2, Bid=exA, group=2)
1 1:2.000 2:3.000 3:0.000 4:0.000 5:0.000 #(Aid=sub3, Bid=exA, group=1)
2 1:0.000 2:5.000 3:1.000 4:2.000 5:0.000 #(Aid=sub4, Bid=exA, group=2)
1 1:0.000 2:1.000 3:1.000 4:2.000 5:0.000 #(Aid=sub5, Bid=exA, group=1)
1 1:5.000 2:0.000 3:1.000 4:3.000 5:0.000 #(Aid=sub6, Bid=exA, group=1)
2 1:1.000 2:0.000 3:1.000 4:1.000 5:0.000 #(Aid=sub7, Bid=exA, group=2)
1 1:4.000 2:2.000 3:0.000 4:1.000 5:0.000 #(Aid=sub8, Bid=exA, group=1)
2 1:0.000 2:1.000 3:0.000 4:4.000 5:0.000 #(Aid=sub9, Bid=exA, group=2)
2 1:0.000 2:0.000 3:1.000 4:0.000 5:0.000 #(Aid=sub10, Bid=exA, group=2)
2 1:4.000 2:2.000 3:1.000 4:2.000 5:0.000 #(Aid=sub11, Bid=exA, group=2)
2 1:0.000 2:4.000 3:1.000 4:2.000 5:0.000 #(Aid=sub12, Bid=exA, group=2)
1 1:4.000 2:2.000 3:1.000 4:0.000 5:0.000 #(Aid=sub13, Bid=exA, group=1)
1 1:2.000 2:0.000 3:1.000 4:1.000 5:0.000 #(Aid=sub14, Bid=exA, group=1)

Я хочу использовать данные из столбца 7 (заголовок: Set) файла file1.tsv для создания новых файлов, в которых будут напечатаны соответствующие строки из file2.vec, и для каждой итерации я хочу добавить новую строку к предыдущему выводу. Так, например, первая строка (если мы не считаем заголовок) - это sub9 в file1.tsv, и соответствующие данные из file2.vec могут быть связаны с помощью Aid, так что результат будет:

out1.vec 
2 1:0.000 2:1.000 3:0.000 4:4.000 5:0.000

Теперь я хочу иметь несколько выходов, подобных этому:

out2.vec 
2 1:0.000 2:1.000 3:0.000 4:4.000 5:0.000
1 1:2.000 2:0.000 3:1.000 4:1.000 5:0.000

out3.vec 
2 1:0.000 2:1.000 3:0.000 4:4.000 5:0.000
1 1:2.000 2:0.000 3:1.000 4:1.000 5:0.000
1 1:5.000 2:0.000 3:1.000 4:3.000 5:0.000

...
out4-13

out14.vec 
2 1:0.000 2:1.000 3:0.000 4:4.000 5:0.000
1 1:2.000 2:0.000 3:1.000 4:1.000 5:0.000
1 1:5.000 2:0.000 3:1.000 4:3.000 5:0.000
2 1:0.000 2:1.000 3:2.000 4:5.000 5:0.000
1 1:4.000 2:2.000 3:1.000 4:0.000 5:0.000
1 1:0.000 2:1.000 3:1.000 4:2.000 5:0.000
1 1:4.000 2:2.000 3:0.000 4:1.000 5:0.000
2 1:1.000 2:0.000 3:1.000 4:1.000 5:0.000
2 1:0.000 2:4.000 3:1.000 4:2.000 5:0.000
1 1:3.000 2:0.000 3:0.000 4:4.000 5:0.000
2 1:0.000 2:0.000 3:1.000 4:0.000 5:0.000
1 1:2.000 2:3.000 3:0.000 4:0.000 5:0.000
2 1:0.000 2:5.000 3:1.000 4:2.000 5:0.000
2 1:4.000 2:2.000 3:1.000 4:2.000 5:0.000

У меня есть каталог с несколькими файлами, такими как file1.tsv, и для каждого файла я хочу выполнить процедуру, описанную ранее. Поэтому я попытался написать сценарий оболочки:

# first to extract column 7 
for filename in File; do
        listFile=$(basename "$filename" .tsv)-cmpdsList.tsv
        awk '{if (NR!=1) {print $7}}' $filename \
        > $listFile
done

# second to generate files containing lines from previously generated list
for line in $(cat $listFile); do
        echo "$line" > $line.vec
done

# add information corresponding to the compounds to generate vector file
for file in $line.vec; do
        output=$(basename "$line.vec" .vec)-output.vec
        gawk 'BEGIN {RS="\n"; ORS="\n"} (NR==FNR){a[$1]=$0; next} ($1 in a){print a[$1]}' $file RS="\n" $line.vec > $output
 done

Но он генерирует только пустые векторные файлы. Спасибо!

1 Ответ

0 голосов
/ 04 июня 2019

Первые комментарии к вашему коду:

# first to extract column 7 
for filename in File; do
  • File - это строка. Возможно, вы хотите, чтобы файл был здесь?
        listFile=$(basename "$filename" .tsv)-cmpdsList.tsv
        awk '{if (NR!=1) {print $7}}' $filename \
        > $listFile
  • Команда awk может быть сокращена до: awk 'NR>1 {print $7}' ...
  • Безопаснее процитировать использование $listFile: "$listFile"
done

# second to generate files containing lines from previously generated list
for line in $(cat $listFile); do
        echo "$line" > $line.vec
done
  • Если $line равно sub9 или как-то так, оно также не может быть out1
# add information corresponding to the compounds to generate vector file
for file in $line.svm; do
        output=$(basename "$line.svm" .svm)-output.vec
        gawk 'BEGIN {RS="\n"; ORS="\n"} (NR==FNR){a[$1]=$0; next} ($1 in a){print a[$1]}' $file RS="\n" $line.svm > $output
 done
  • В ваших примерах нет файлов .svm, поэтому этот код трудно интерпретировать

возможное решение awk

На основании ваших file1.tsv и file2.vec (при условии отсутствия 1 в начале первой строки - опечатка) и описания выходных данных, возможное решение awk:

awk '
    NR==FNR && NR>1 {
        n++
        aid[$7] = n
        next
    }
    NR!=FNR {
        pat = $7
        sub(/^#[(]Aid=/, "", pat)
        sub(/,$/, "", pat)
        sub(/ #.*$/, "", $0)
        line[ aid[pat] ] = $0
    }
    END {
        for (i=1; i<=n; i++) {
            out = "out" i ".vec"
            printf "" > out
            for (j=1; j<=i; j++) {
                print line[j] >> out
            }
            close(out)
        }
    }
' file1.tsv file2.vec
  • NR==FNR ... - вытащить идентификатор и сопоставить его с номером строки
  • NR!=FNR ... - отработать строку из id в $7, убрать конечные поля из $0 и сохранить
  • END ... - для каждой строки выведите ее и все предшествующие соответствующему выходному файлу
  • close - закрыть файл после записи, чтобы избежать исчерпания файловых дескрипторов
...