Шаблон регулярного выражения, который распознает расширение файла в скрипте Bash, не точное для захвата сжатых файлов

Я создал этот маленький скрипт Bash, который имеет один аргумент (имя файла), и скрипт должен отвечать в соответствии с расширением файла:

#!/bin/bash

fileFormat=${1}

if [[ ${fileFormat} =~ [Ff][Aa]?[Ss]?[Tt]?[Qq]\.?[[:alnum:]]+$ ]]; then
    echo "its a FASTQ file";
elif [[ ${fileFormat} =~ [Ss][Aa][Mm] ]]; then
    echo "its a SAM file";
else
    echo "its not fasta nor sam";
fi

Это работает так:

sh script.sh filename.sam

Если это fastq (или FASTQ, или fq, или FQ, или fastq.gz (сжатый)), я хочу, чтобы скрипт сказал мне "это fastq". Если это Сэм, я хочу, чтобы он сказал мне, что это Сэм, а если нет, я хочу сказать мне, что это ни Сэм, ни fastq.

ПРОБЛЕМА: когда я не рассматривал сценарий.gz (сжатый), сценарий работал хорошо и давал ожидаемый результат, но что-то происходит, когда я пытаюсь добавить эту последнюю часть для объяснения этой ситуации (см. Третью строку, часть, где говорится.?[[:alnum:]]+). Эта часть предназначена для того, чтобы сказать "в имени файла после расширения (в данном случае fastq) может быть точка плюс некоторое слово после".

Мой вклад это:

sh script.sh filename.fastq.gz

И это работает. Но если я поставлю: sh script.sh filename.fastq

Это говорит, что это не fastq. Я хотел поставить эту последнюю часть как дополнительную, но если я добавлю "?" в конце это не работает. Какие-нибудь мысли? Спасибо! Мой вопрос заключается в том, чтобы исправить эту часть, чтобы работать в обоих случаях.

2 ответа

Решение

Вы можете использовать это регулярное выражение:

fileFormat="$1"

if [[ $fileFormat =~ [Ff]([Aa][Ss][Tt])?[Qq](\.[[:alnum:]]+)?$ ]]; then
    echo "its a FASTQ file"
elif [[ $fileFormat =~ [Ss][Aa][Mm]$ ]]; then
    echo "its a SAM file"
else
    echo "its not fasta nor sam"
fi

Вот (\.[[:alnum:]]+)? делает последнюю группу необязательной, которая представляет собой точку, за которой следуют 1+ буквенно-цифровые символы.

Когда вы запускаете его как:

./script.sh filename.fastq
its a FASTQ file

./script.sh fq
its a FASTQ file

./script.sh filename.fastq.gz
its a FASTQ file

./script.sh filename.sam
its a SAM file

./script.sh filename.txt
its not fasta nor sam

Непосредственной проблемой является то, что вам требуется хотя бы один [[:alnum:]] символ после .fastq, Это легко исправить само по себе с * вместо +,

Однако Regex - не особо удачное решение этой проблемы.

case $fileFormat in
    *.[Ff][Aa][Ss][Tt][Qq] | *.[Ff][Aa][Ss][Tt][Qq].*)
        echo "$0: $fileFormat is a FASTQ file" >&2 ;;
    *.[Ss][Aa][Mm] )
        echo "$0: $fileFormat is a SAM file" >%2 ;;
esac

портативен вплоть до оригинальной Bourne sh, В Bash 4.x перед сравнением можно прописать имя файла в нижнем регистре, чтобы упростить шаблоны глобусов.

Обратите также внимание на то, что диагностика содержит имя сценария и выводит на печать со стандартной ошибкой вместо стандартного вывода.

Другие вопросы по тегам