Список файлов в качестве входного аргумента для скрипта bash - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть список файлов:

path/dir/*.gz

И я хочу предоставить этот список файлов в качестве входных данных в моем bash-скрипте вместе с другими аргументами, связанными с анализом (то есть выходной папкой и количеством потоков).

./myscript.sh path/dir/*.gz output_path 2

myscript.sh включает в себя следующую команду:

fastqc $1 -o $2 -t $3 --noextract -d ./

Программа fastqc может в несколько потоков запускать список входных файлов. Я использую этот скрипт в кластере SGE, поэтому использую команду "qsub". И я запустил его следующим образом:

qsub ./myscript.sh path/dir/*.gz output_path 2

Однако это не работает. Кто-то знает почему и может предложить решение? Насколько я понимаю, я испортил список входных файлов в качестве аргумента.

1 Ответ

0 голосов
/ 10 сентября 2018

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

Вот несколько стратегий:

  1. выберите последние 2 аргумента из списка:

    #!/bin/bash
    
    if (( $# < 3 )); then
        echo not enough arguments
        exit 1
    fi
    
    # threads is the last argument
    n=$#
    threads=${!n}
    
    # output_path is the 2nd-last argument
    ((n--))
    output_path=${!n}
    
    # discard the last 2 arguments
    ((n--))
    set -- "${@:1:n}"
    
    # now "$@" is the list of input files.
    for file in "$@"; do
        fastqc "$file" -o "$output_path" -t "$threads" --noextract -d ./
    done
    

    При этом используются "косвенные переменные" (${!n}) для извлечения значения позиционного параметра для числа $ n.

  2. использовать параметры командной строки для указания пути вывода и количества потоков:

    #!/bin/bash
    while getopts :o:t:h opt; do
        case $opt in
            h) show_help; exit ;;
            o) output_path=$OPTARG ;;
            t) threads=$OPTARG ;;
            *) exit ;; # some error
        esac
    done
    
    if [[ -z $output_path ]]; then
        echo error message
        exit 1
    fi
    if [[ -z $threads ]]; then 
        echo error message
        exit 1
    fi
    # other validations, like $threads is a sensible whole number
    
    shift $((OPTIND - 1))
    
    # now "$@" is the list of input files.
    for file in "$@"; do
        fastqc "$file" -o "$output_path" -t "$threads" --noextract -d ./
    done
    

Я не знаю fastqc, но если он может принимать несколько входных файлов, тогда вместо цикла выполните

fastqc "$@" -o "$output_path" -t "$threads" --noextract -d ./
...