识别 Bash 脚本中文件扩展名的正则表达式模式对于捕获压缩文件不准确

Regex pattern that recognises file extension in Bash script not accurate to capture compressed files

我创建了这个带有一个参数(文件名)的小 Bash 脚本,该脚本应该根据文件的扩展名做出响应:

#!/bin/bash

fileFormat=

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(压缩)),我希望脚本告诉我 "it's a fastq"。如果是 sam,我希望它告诉我它是 sam,如果不是,我想告诉我它既不是 sam 也不是 fastq。

问题: 当我没有考虑 .gz(压缩)场景时,脚本 运行 很好并给出了我预期的结果,但有些东西是当我尝试添加最后一部分以说明这种情况时发生(请参阅第三行,它说的部分 .?[[:alnum:]]+ )。这部分的意思是"in the filename, after the extension (fastq in this case), there might be a dot plus some word afterwards".

我的输入是这样的:

sh script.sh filename.fastq.gz

并且有效。但如果我把: sh script.sh filename.fastq

上面说不是fastq。我想把最后一部分作为可选的,但是如果我添加一个“?”最后它不起作用。有什么想法吗?谢谢! 我的问题是修复该部分以适用于这两种情况。

眼前的问题是您需要在 .fastq 之后至少有一个 [[:alnum:]] 个字符。使用 * 而不是 +.

本身很容易修复

不过,正则表达式并不是解决此问题的特别好的解决方案。

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

可移植到原版谍影重重 sh。在 Bash 4.x 中,您可以在比较之前将文件名小写,以简化 glob 模式。

另请注意诊断如何包含脚本的名称并打印到标准错误而不是标准输出。

您可以使用这个正则表达式:

fileFormat=""

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