awk :cmd. строка :1:(FILENAME=file2split FNR=1666 )фатальный :невозможно перенаправить на `CCTGGCAG _GATATAAC _HAP1' (Операция не разрешена)

Мое (запутанное )предложение:

cat file | grep -Po "^[CGTA-]*$|^>.*$" | grep -Po "(?<=\[).*(?=])|^[ACGT-]*$" | awk '{printf (NR%2==0) ? $0 "\n" : ">"$0"::"}' | sort | sed 's/#/\n/'

Grep только строки, содержащие символы CGTA-и строки, начинающиеся с>

grep -Po "^[CGTA-]*$|^>.*$"

Grep только то, что находится внутри скобок, исключая их и строки, соответствующие шаблонуACGT-

| grep -Po "(?<=\[).*(?=])|^[ACGT-]*$"

Соедините каждые две строки, добавив разделитель #и начальную >, затем отсортируйте

| awk '{printf (NR%2==0) ? $0 "\n" : ">"$0"#"}' | sort

Наконец, замените разделитель #новой строкой

| sed 's/#/\n/'

Выход:

>Archaeoglobus_fulgidus_DSM_4304.gbfspecies
ATGCGCGCGATAGCTAGCTAGCTAGCTTTAGGGGGATTAGCTA----ACTCTGATTCGGA
>Ignicoccus_hospitalis_KIN4-I.gbfspecies
ATGAGTGTGACTA---TTT---GCAATCAGCTAGCTACTACGTACTGATCGTAGCTGACG
1
19.08.2021, 00:43
2 ответа

Вы можете избежать ограничения количества открытых -файлов, закрывая предыдущее имя файла всякий раз, когда изменяется имя текущего выходного файла. например.

awk '{ out=$1;
       if (out != lastfile) {
         if (lastfile != "") { close(lastfile) };
         lastfile = out
     };
     print > out'

Это значительно лучше, чем закрытие файла и повторное -открытие его при каждой записи. Он закрывает файл только тогда, когда имя файла изменилось с момента последней записи. Если файл отсортирован по полю 1, ему никогда не придется повторно -открывать файл... а если он "в основном отсортирован", ему редко придется повторно -открывать файл.

Обратите внимание, :если одно и то же имя файла может встречаться более одного раза в не -смежных строках, вы должны добавить к выводу print >> outвместо print > out, в противном случае, когда файл Если повторно -открыт для записи, он будет полностью перезаписан -(, т.е. усечен до нулевого размера )перед этой записью.

(Кстати, это одна из причин, почему awkне закрывает файл автоматически после каждой записи. Другая основная причина, конечно,заключается в том, что намного медленнее закрывать и повторно -открывать одни и те же файлы для каждой записи, если вам не нужно)

Это немного сложнее, если вы хотите перезаписать файл в первый раз, когда он виден в любом заданном запуске скрипта awk, но добавить, если тот же файл снова виден в том же запуске. например.

awk '{ out=$1;
       if (out != lastfile) {
         if (lastfile != "") { close(lastfile) };
         lastfile = out
     };

     if (seen[out]++) {
       print >> out
     } else {
       print > out
     }'

В этой версии используется ассоциативный массив seenдля отслеживания того, видели ли мы ранее имя файла или нет. Если да, доп. если нет, перезапишите.

1
20.08.2021, 10:24

Я сомневаюсь, что слишком много одновременно открытых файлов действительно вызывает вашу текущую проблему, но, к вашему сведению, надежным и эффективным способом сделать то, что вы пытаетесь сделать, является следующее использование сортировки GNU для -sи любого awk:

zcat file2split.gz |
sort -s -k1,1 |
awk '
    $1 != out {
        close(out)
        out = $1
    }
    { print > out }
'

Если у вас нет сортировки GNU, вы можете сделать то же самое с любой версией этих стандартных инструментов Unix:

zcat file2split.gz |
awk -v OFS='\t' '{print NR, $0}' |
sort -k2,2 -k1,1n |
cut -f2- |
awk '
    $1 != out {
        close(out)
        out = $1
    }
    { print > out }
'

При описанном выше подходе к сортировке входных данных до того, как awk начнет создавать выходные файлы, awk одновременно открывает только 1 выходной файл и никогда не должен открывать выходной файл более одного раза, он просто открывает его, пишет все связанные с ним строки, затем закрывает его и переходит к следующему выходному файлу.

1
20.08.2021, 10:24

Теги

Похожие вопросы