добавить вывод каждой итерации цикла к тому же в bash - PullRequest
0 голосов
/ 15 января 2019

У меня есть 44 файла (по 2 на каждую хромосому), разделенных на два типа: .vcf и .filtered.vcf. Я хотел бы сделать wc -l для каждого из них в цикле и добавить вывод всегда в один и тот же файл. Однако я хотел бы иметь 3 столбца в этом файле: chr [1-22], wc -l из .vcf и wc -l из .filtered.vcf.

Я пытался сделать независимым wc -l для каждого файла и вставить по столбцам по два вывода для каждой из хромосом, но это, очевидно, не очень эффективно, потому что я генерирую много ненужных файлов. Я пытаюсь этот код для 22 пар файлов:

wc -l file1.vcf | cut -f 1 > out1.vcf
wc -l file1.filtered.vcf | cut -f 1 > out1.filtered.vcf
paste -d "\t" out1.vcf out1.filtered.vcf

Я хотел бы иметь только один выходной файл, содержащий три столбца:

Chromosome    VCFCount    FilteredVCFCount
chr1          out1        out1.filtered
chr2          out2        out2.filtered

Буду признателен за любую помощь, большое спасибо заранее :)

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Может быть, попробовать это.

for chr in chr*.vcf; do
    base=${chr%.vcf}
    awk -v base="$base" 'BEGIN { OFS="\t"
            # Remove this to not have this pesky header line
            print "Chromosome", "VCFCount", "FilteredVCFCount"
            }
        FNR==1 && n { p=n }
        { n=FNR }
        END { print base, p, n }' "$chr" "$base.filtered.vcf"
done >counts.txt

Очень простой скрипт Awk просто собирает наибольший номер строки для каждого файла (поэтому мы в основном переопределяем wc -l) и печатает собранные числа в нужном формате. FNR - номер строки в текущем входном файле; мы просто сохраняем это и копируем значение в p, чтобы сохранить сохраненное значение из предыдущего файла в отдельной переменной, когда мы переключаемся на новый файл (начиная со строки № 1).

Подстановка параметра оболочки ${variable%pattern} извлекает значение variable с любым совпадением суффикса для pattern. (Существует также ${variable#pattern} для удаления префикса, и у Bash есть ## и %% для обрезки самого длинного совпадения с образцом вместо самого короткого.)

Если важна эффективность, вы, вероятно, могли бы преобразовать весь сценарий в один сценарий Awk, но таким образом все части просты и, надеюсь, понятны.

0 голосов
/ 15 января 2019
printf "%s\n" *.filtered.vcf |
cut -d. -f1 |
sort |
xargs -n1 sh -c 'printf "%s\t%s\t%s\n" "$1" "$(wc -l <"${1}.vcf")" "$(wc -l <"${1}.filtered.vcf")"' -- 
  1. Вывести разделенный новой строкой список файлов в каталоге
  2. Удалите расширение с вырезом (возможно, что-то с xargs -i basename {} .filtered.vcf будет безопаснее)
  3. Сортировка (для хорошего сортированного вывода!) (Вероятно, что-то с sort -tr -k2 -n будет отсортировано численно и будет еще лучше).
  4. xargs -n1 Для каждого файла выполнить скрипт sh -c
    1. printf "%s\t%s\t%s\n" - вывод со строкой произвольного формата ...
    2. "$1" - имя файла и ...
    3. "(wc -l <"${1}.vcf")" - количество строк в файле .vcf и ...
    4. "$(wc -l <"${1}.filtered.vcf")" - количество строк в файле .filtered.vcf

Пример:

> touch chr{1..3}{,.filtered}.vcf 
> echo > chr1.filtered.vcf ; echo  > chr2.vcf ; 
>     printf "%s\n" *.filtered.vcf |
>    cut -d. -f1 |
>    sort |
>    xargs -n1 sh -c 'printf "%s\t%s\t%s\n" "$1" "$(wc -l <"${1}.filtered.vcf")" "$(wc -l <"${1}.vcf")"' -- 
chr1    0   1
chr2    1   0
chr3    0   0

Чтобы иметь красивый стол с заголовками, используйте column:

> .... | column -N Chromosome,VCFCount,FilteredVCFCount -t -o '    '
Chromosome    VCFCount    FilteredVCFCount
chr1          0           1
chr2          1           0
chr3          0           0
...