Улучшен скрипт bash для получения базовой статистики по файлам

Вы можете использовать комбинацию printf,xargs:

Программа printf выдает числа от 1 до 5 по одному за раз -n 1, текущее число фиксируется в {}и затем передается в shв командной строке. Затем аргумент используется для построения соответствующей команды mv.

printf '%d\n' {1..5} | xargs -n 1 -I {} sh -c 'mv "0$1".* "Season $1"' {} {}
0
14.09.2020, 10:43
2 ответа

Следующий сценарий awkвыполнит эту задачу. Я напишу его как явный файл программы awkиз-за длины -, которая в основном связана с функцией печати результатов анализа;фактические расчеты довольно короткие:

Если у вас есть GNU awkдля блока ENDFILE:

Программный файл (назовем егоanalyze_genome_g.awk):

#!/usr/bin/gawk -f

# Begin of file, characterized by FNR, the per-file line-counter, being 1.
# Initialize statistics: set sum, min, and max to first chromosome length
# and name of longest/shortest ('long'/'short') to first chromosome name.
FNR==1{s=min=max=$2; short=long=$1}

# All other lines: Update sum, min, and max lengths
FNR>1{s=s+$2;if (min>$2) {min=$2; short=$1}; if (max<$2) {max=$2; long=$1}}

# End-of-file (GNU awk feature!): Print statistics
ENDFILE{
    printf("%s\n",FILENAME);
    printf("- Genome length         : %d\n",s);
    printf("- Nr. of chromosomes    : %d\n",FNR);
    printf("- Mean chomosome length : %.1f\n",s/FNR);
    printf("- Shortest chromosome   : %s (length=%d)\n",short,min);
    printf("- Longest chromosome    : %s (length=%d)\n",long,max);
    printf("\n");
}

Вы можете назвать это как

gawk -f analyze_genome_g.awk file_1 file_2...

Выход:

file_1
- Genome length         : 100286070
- Nr. of chromosomes    : 7
- Mean chomosome length : 14326581.4
- Shortest chromosome   : chrM (length=13794)
- Longest chromosome    : chrV (length=20924149)

file_2
- Genome length         : 12157105
- Nr. of chromosomes    : 17
- Mean chomosome length : 715123.8
- Shortest chromosome   : chrM (length=85779)
- Longest chromosome    : chrIV (length=1531933)

Другие awkварианты:

Если ваш awkне знает условия ENDFILE, требуется небольшой обходной путь -в основном сохранение свойств файла во временных переменных и печать статистики либо в начале нового файла (для предыдущий файл )или в блоке ENDпри обработке последнего файла.

Чтобы сделать это более удобным, мы определяем функцию printstats(), которая выполняет вывод.

Файл программы(analyze_genome.awk):

#!/usr/bin/awk -f
function printstats()
{
    printf("%s\n",last_fn);
    printf("- Genome length         : %d\n",s);
    printf("- Nr. of chromosomes    : %d\n",last_fnr);
    printf("- Mean chomosome length : %.1f\n",s/last_fnr);
    printf("- Shortest chromosome   : %s (length=%d)\n",short,min);
    printf("- Longest chromosome    : %s (length=%d)\n",long,max);
    printf("\n");
}

# Begin of file
# FNR==1 always works, but now we have to save file properties, too.
# If it is _not_ the first file (NR, the global line counter, is larger than
# FNR, the per-file line-counter), print statistics (of the previous file).
FNR==1{
    if (NR>1) printstats();
    s=min=max=$2; short=long=$1;
    last_fn=FILENAME; last_fnr=1;
}


FNR>1{
    s=s+$2; if (min>$2) {min=$2; short=$1}; if (max<$2) {max=$2; long=$1};
    last_fnr++;
}

END{printstats()}

Вы можете вызвать его аналогично

awk -f analyze_genome.awk file_1 file_2...

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

2
18.03.2021, 23:05

Вы можете создавать свои статистические отчеты в формате yaml, используя версию настольного калькулятора GNU. Ниже приведена сильно прокомментированная версия кода постоянного тока.

#!/usr/bin/env bash
for VARIABLE in Data/*.sizes
do
    printf '%s:\n' "$VARIABLE" 
< "$VARIABLE" awk '{$1="["$1"]";sub(/^-/,"_",$2)}1' \
| dc -e "
[32adnn]si  # two-spaces indent in reporting
[
lix[Genome length:]   n32an lsp
lix[Chr number:]      n32an lkp
lix[Chr mean length:] n32an /1.0*p
lix[Longest Chr:]     n32an lM     n32an lmp
lix[Smallest Chr:]    n32an lN     n32an lnp
q
]sR
[dsmrdsMr]s+
[dsnrdsNr]s-
[
?z0=R  # report stats @ eof
lk1+sk # increment line kounter
dls+ss # update running sum
dlm<+  # update max
dln>-  # update min
cz0=?  # call myself recursively to read next line 
]s?
[
?       # read the first line
1skdss  # initialize knt, sum
dsmrdsM # initialize max
sNsn    # initialize min
cl?x    # read next line
]sI
lIx     # set the ball rolling, kinda like main() 
"

Результаты:

Data/file_1.sizes:
  Genome length: 100286070
  Chr number: 7
  Chr mean length: 14326581.0
  Longest Chr: chrV 20924149
  Smallest Chr: chrM 13794

Data/file_2.sizes:
  Genome length: 12157105
  Chr number: 17
  Chr mean length: 715123.0
  Longest Chr: chrIV 1531933
  Smallest Chr: chrM 85779
1
18.03.2021, 23:05

Теги

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