如何在单个函数中合并 zcat 和 bzcat

How to merge zcat and bzcat in a single function

我想构建一个可以处理 fastq.gz 和 fastq.bz2 文件的小辅助函数。

我想将 zcat 和 bzcat 合并为一个透明函数,可以用于两种文件:

zbzcat example.fastq.gz
zbzcat example.fastq.bz2


zbzcat() {
  file=`echo  | `
## Not working
  ext=${file##*/};
  
  if [ ext == "fastq.gz" ]; then
    exec gzip -cd "$@"  
  else
    exec bzip -cd "$@"  
  fi
}

扩展提取工作不正常。您知道其他解决方案吗

ext=${1##*.}

为什么要输入 echo 并尝试剥离 /

此外,字符串 ext(3 个字符)永远不会等于字符串 fastq.gz(7 个字符)。如果要检查扩展名是否等于 gz,只需执行

if [[ $ext == gz ]]

话虽如此,依靠扩展名来了解文件的内容有点勇敢。也许更可靠的方法是使用 file 来确定最可能的文件类型。可能最安全的方法是先尝试 bzip 提取,如果失败,再进行 gzip 提取。

这些问题挺多的:

  • file=`echo | ` 给出语法错误,因为|之后没有命令。但是无论如何您都不需要命令替换。只需使用 file=.
  • ext=${file##*/} 不是提取扩展名,而是提取文件名。要提取扩展名,请使用 ext=${file##*.}.
  • 在你的检查中你没有使用变量 $ext 而是文字字符串 ext.
  • 通常,只有文件名中最后一个点之后的字符串才被认为是扩展名。如果您有 file.fastq.gz,则扩展名是 gz。所以使用检查$ext = gz。未压缩的文件是 fastq 文件与函数无关。
  • exec 用给定的命令替换 shell 进程。因此,在执行您的函数后,shell 将退出。执行命令即可。

顺便说一句:使用模式匹配时,您根本不必提取扩展名:

zbzcat() {
  file=""
  case "$file" in
    *.gz) gzip -cd "$@";;
    *.bz2) bzip -cd "$@";;
    *) echo "Unknown file format" >&2;;
  esac
}

或者,使用支持多种格式的 7z x。大多数发行版将包命名为 p7zip.

我想如果你使用mimetype会更好。

文件扩展名并不总是正确的。

decomp() {  
  case $(file -b --mime-type  )  in
    "application/gzip")
         gzip -cd "$@"
         ;;
    "application/x-bzip2")
         bzcat  "$@"
         ;;
    "application/x-xz")
        xzcat "$@"
        ;;
    *) 
      echo "Unknown file format" >&2
    ;;
  esac
}